<commit_before>"use strict";

var path = require("path");

module.exports = function (grunt) {

    // Load grunt tasks automatically
    require("load-grunt-tasks")(grunt);

    // Time how long tasks take
    require("time-grunt")(grunt);

    // Define configuration for all tasks
    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        webpack: {
            options: {
                stats: !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
            },
            prod: require("./conf/webpack.config.js"),
            dev: Object.assign({ watch: true }, require("./conf/webpack.config.js"))
        },

        mocha_istanbul: {
            coverage: {
                src: ["test/unit-helper.js", "app/**/*.spec.js"],
                options: {
                    mask: '**/*.js',
                    require: ['test/mocha-babel'],
                    coverageFolder: 'dist/coverage',
                    mochaOptions: ['--compilers', 'js:babel-core/register'],
                    istanbulOptions: ['--handle-sigint']
                }
            }
        },

        nwjs: {
            options: {
                platforms: ['win','osx64', 'linux'],
                buildDir: './dist/packages/',
                buildType: 'default',
                cacheDir: '.cache'
            },
            src: ['./dist/webpack/**/*', './package.json', './LICENSE.md']
        },

        clean: {
            dist: ["dist"],
            webpack: ["dist/webpack"],
            coverage: ["dist/coverage/"],
            reports: ["dist/test-reports/"],
            doc: ["dist/doc/"],
            packageTmp: ["dist/packages/CodeCharta"],
            package: ["dist/packages/"]
        },

        exec: {
            doc: {
                command: path.resolve("node_modules", ".bin", "esdoc") + " -c conf/esdoc.json",
                stdout: true
            },
            karmaSingle: {
                command: path.resolve("node_modules", ".bin", "karma") + " start ./conf/karma.config.js",
                stdout: true
            },
            karmaAuto: {
                command: path.resolve("node_modules", ".bin", "karma") + " start ./conf/karma.auto.config.js",
                stdout: true
            }
        },

        compress: {
            web: {
                options: {
                    archive: './dist/packages/codecharta-web.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/webpack/", src: ['**/*'], dest: '.'}
                ]
            },
            linux32: {
                options: {
                    archive: './dist/packages/codecharta-visualization-linux32.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/linux32/", src: ['**/*'], dest: '.'}
                ]
            },
            linux64: {
                options: {
                    archive: './dist/packages/codecharta-visualization-linux64.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/linux64/", src: ['**/*'], dest: '.'}
                ]
            },

            win32: {
                options: {
                    archive: './dist/packages/codecharta-visualization-win32.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/win32/", src: ['**/*'], dest: '.'}
                ]
            },
            win64: {
                options: {
                    archive: './dist/packages/codecharta-visualization-win64.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/win64/", src: ['**/*'], dest: '.'}
                ]
            }

        }

    });

    // tasks
    grunt.registerTask("default", ["build"]);
    grunt.registerTask("build", ["clean:webpack", "webpack:prod"]);
    grunt.registerTask("serve", ["clean:webpack", "webpack:dev"]);
    grunt.registerTask("package", ["clean:package", "nwjs", "force:compress", "clean:packageTmp"]);
    grunt.registerTask("doc", ["clean:doc", "exec:doc"]);
    grunt.registerTask("test", ["clean:coverage", "clean:reports", "exec:karmaSingle"]);
    grunt.registerTask("test:auto", ["clean:coverage", "clean:reports", "exec:karmaAuto"]);

};
<commit_msg>temporary: disabled native nwjs packages due to decompress/nwjs bug<commit_after>"use strict";

var path = require("path");

module.exports = function (grunt) {

    // Load grunt tasks automatically
    require("load-grunt-tasks")(grunt);

    // Time how long tasks take
    require("time-grunt")(grunt);

    // Define configuration for all tasks
    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        webpack: {
            options: {
                stats: !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
            },
            prod: require("./conf/webpack.config.js"),
            dev: Object.assign({ watch: true }, require("./conf/webpack.config.js"))
        },

        mocha_istanbul: {
            coverage: {
                src: ["test/unit-helper.js", "app/**/*.spec.js"],
                options: {
                    mask: '**/*.js',
                    require: ['test/mocha-babel'],
                    coverageFolder: 'dist/coverage',
                    mochaOptions: ['--compilers', 'js:babel-core/register'],
                    istanbulOptions: ['--handle-sigint']
                }
            }
        },

        nwjs: {
            options: {
                platforms: ['win','osx64', 'linux'],
                buildDir: './dist/packages/',
                buildType: 'default',
                cacheDir: '.cache'
            },
            src: ['./dist/webpack/**/*', './package.json', './LICENSE.md']
        },

        clean: {
            dist: ["dist"],
            webpack: ["dist/webpack"],
            coverage: ["dist/coverage/"],
            reports: ["dist/test-reports/"],
            doc: ["dist/doc/"],
            packageTmp: ["dist/packages/CodeCharta"],
            package: ["dist/packages/"]
        },

        exec: {
            doc: {
                command: path.resolve("node_modules", ".bin", "esdoc") + " -c conf/esdoc.json",
                stdout: true
            },
            karmaSingle: {
                command: path.resolve("node_modules", ".bin", "karma") + " start ./conf/karma.config.js",
                stdout: true
            },
            karmaAuto: {
                command: path.resolve("node_modules", ".bin", "karma") + " start ./conf/karma.auto.config.js",
                stdout: true
            }
        },

        compress: {
            web: {
                options: {
                    archive: './dist/packages/codecharta-web.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/webpack/", src: ['**/*'], dest: '.'}
                ]
            },
            linux32: {
                options: {
                    archive: './dist/packages/codecharta-visualization-linux32.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/linux32/", src: ['**/*'], dest: '.'}
                ]
            },
            linux64: {
                options: {
                    archive: './dist/packages/codecharta-visualization-linux64.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/linux64/", src: ['**/*'], dest: '.'}
                ]
            },

            win32: {
                options: {
                    archive: './dist/packages/codecharta-visualization-win32.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/win32/", src: ['**/*'], dest: '.'}
                ]
            },
            win64: {
                options: {
                    archive: './dist/packages/codecharta-visualization-win64.zip'
                },
                files: [
                    {expand: true, cwd:"./dist/packages/CodeCharta/win64/", src: ['**/*'], dest: '.'}
                ]
            }

        }

    });

    // tasks
    grunt.registerTask("default", ["build"]);
    grunt.registerTask("build", ["clean:webpack", "webpack:prod"]);
    grunt.registerTask("serve", ["clean:webpack", "webpack:dev"]);
    grunt.registerTask("package", ["clean:package", /*"nwjs",*/ "compress:web", "clean:packageTmp"]);
    grunt.registerTask("doc", ["clean:doc", "exec:doc"]);
    grunt.registerTask("test", ["clean:coverage", "clean:reports", "exec:karmaSingle"]);
    grunt.registerTask("test:auto", ["clean:coverage", "clean:reports", "exec:karmaAuto"]);

};
<|endoftext|>


<commit_before>var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');

module.exports = {
  output: {
    publicPath: '/',
    libraryTarget: 'commonjs2',
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
    modules: [
      'client',
      'node_modules',
    ],
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',
      },
      {
        test: /\.jpe?g$|\.gif$|\.png$|\.svg$/i,
        loader: 'url-loader?limit=10000',
      },
    ],
  },
  postcss: () => [
    postcssFocus(),
    cssnext({
      browsers: ['last 2 versions', 'IE > 10'],
    }),
    postcssReporter({
      clearMessages: true,
    }),
  ],
};
<commit_msg>Fix CSS Modules ident name for production build (from Sai Kishore Komanduri)<commit_after>var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');

var cssModulesIdentName = '[name]__[local]__[hash:base64:5]';
if (process.env.NODE_ENV === 'production') {
  cssModulesIdentName = '[hash:base64]';
}

module.exports = {
  output: {
    publicPath: '/',
    libraryTarget: 'commonjs2',
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],
    modules: [
      'client',
      'node_modules',
    ],
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        loader: 'style-loader!css-loader?localIdentName=' + cssModulesIdentName + '&modules&importLoaders=1&sourceMap!postcss-loader',
      },
      {
        test: /\.jpe?g$|\.gif$|\.png$|\.svg$/i,
        loader: 'url-loader?limit=10000',
      },
    ],
  },
  postcss: () => [
    postcssFocus(),
    cssnext({
      browsers: ['last 2 versions', 'IE > 10'],
    }),
    postcssReporter({
      clearMessages: true,
    }),
  ],
};
<|endoftext|>


<commit_before>var compareState = 0;
var compare1 = null, compare2 = null;
function cancelCompare () {
    $("#filter-detail-table").removeClass("select-compare1");
    $("#filter-detail-table").removeClass("select-compare2");
    $("#filter-detail-table").removeClass("select-compare3");
    $("#filter-detail-table tr").removeClass("selected-1");
    $("#filter-detail-table tr").removeClass("selected-2");
    $("#filter-detail-table tr").unbind("click");
    $("#filter-detail-table tr").unbind("hover");
    $("#filter-detail-table tr").each(removeCheckbox);
    $("#first-prompt").hide();
    $("#second-prompt").hide();
    $("#third-prompt").hide();
    $("#compare-button").button({label:"Compare builds"});
    compareState = 0;
}
function startCompare () {
    $("#compare-button").button({label:"Cancel"});
    $("#filter-detail-table").addClass("select-compare1");
    $("#filter-detail-table tr").click(rowClickHandler);
    $("#filter-detail-table tr").each(insertCheckbox);
    $("#filter-detail-table tr").hover(rowHoverHandlerIn, rowHoverHandlerOut);
    $("#first-prompt").show();
    compareState = 1;
}
function tagFromRow(tr) {
    var firstCell = $(tr).find("td:eq(0)");
    return {
        machinetag: firstCell.find("span").data("machinetag"),
        usertag: firstCell.text()
    };
}
function rowClickHandler() {
    if (compareState == 1) {
        compare1 = tagFromRow($(this));
        $(this).addClass("selected-1");
        $(this).find("input").attr("checked", true);
        $("#p2-build").text(compare1.usertag);
        $("#first-prompt").hide();
        $("#second-prompt").show();
        $("#filter-detail-table").removeClass("select-compare1");
        $("#filter-detail-table").addClass("select-compare2");
        compareState = 2;
    } else if (compareState == 2) {
        var thistag = tagFromRow($(this));
        if (compare1.machinetag == thistag.machinetag) {
            cancelCompare();
            startCompare();
        } else {
            compare2 = thistag;
            $(this).find("input").attr("checked", true);
            $(this).addClass("selected-2");
            $("#second-prompt").hide();
            $("#third-prompt").show();
            $("#filter-detail-table").removeClass("select-compare2");
            $("#filter-detail-table").addClass("select-compare3");
            $("#filter-detail-table input").attr("disabled", true);
            $("#filter-detail-table .selected-1 input").attr("disabled", false);
            $("#filter-detail-table .selected-2 input").attr("disabled", false);
            $("#p3-build-1").text(compare1.usertag);
            $("#p3-build-2").text(compare2.usertag);
            $("#third-prompt a").attr("href", window.location.pathname + '/+compare/' + compare1.machinetag + '/' + compare2.machinetag);
            compareState = 3;
        }
    } else if (compareState == 3) {
        var thistag = tagFromRow($(this));
        if (thistag.machinetag == compare1.machinetag || thistag.machinetag == compare2.machinetag) {
            $("#second-prompt").show();
            $("#third-prompt").hide();
            $("#filter-detail-table").addClass("select-compare2");
            $("#filter-detail-table").removeClass("select-compare3");
            $("#filter-detail-table input").attr("disabled", false);
            compareState = 2;
            $(this).find("input").attr("checked", false);
            if (thistag.machinetag == compare1.machinetag) {
                compare1 = compare2;
                $("#filter-detail-table .selected-1").removeClass("selected-1");
                $("#filter-detail-table .selected-2").addClass("selected-1");
                $("#p2-build").text(compare1.usertag);
            }
            $("#filter-detail-table .selected-2").removeClass("selected-2");
        }
    }
    tagFromRow(this);
}
function rowHoverHandlerIn() {
    $(this).addClass("hover");
}
function rowHoverHandlerOut() {
    $(this).removeClass("hover");
}
function insertCheckbox() {
    var row = $(this);
    var checkbox = $('<input type="checkbox">');
    row.find("td:first").prepend(checkbox);
}
function removeCheckbox() {
    var row = $(this);
    row.find('input').remove();
}
$(window).load(
    function () {
        $("#filter-detail-table").dataTable().fnSettings().fnRowCallback = function(tr, data, index) {
            if (compareState) {
                insertCheckbox.call(tr);
                $(tr).click(rowClickHandler);
                $("#filter-detail-table tr").hover(rowHoverHandlerIn, rowHoverHandlerOut);
                if (compareState >= 2 && tagFromRow(tr).machinetag == compare1.machinetag) {
                    $(tr).addClass("selected-1");
                    $(tr).find("input").attr("checked", true);
                }
                if (compareState >= 3) {
                    if (tagFromRow(tr).machinetag == compare2.machinetag) {
                        $(tr).addClass("selected-2");
                        $(tr).find("input").attr("checked", true);
                    } else if (tagFromRow(tr).machinetag != compare1.machinetag) {
                        $(tr).find("input").attr("disabled", true);
                    }
                }
            }
            return tr;
        };
        $("#compare-button").button();
        $("#compare-button").click(
            function (e) {
                if (compareState == 0) {
                    startCompare();
                } else {
                    cancelCompare();
                }
            }
        );
        $("div.dataTables_length").remove();
        $("div.dataTables_info").remove();
    }

);
<commit_msg>Remove JS code for multi-page compare build selection. Add filter field removal.<commit_after>var compareState = 0;
var compare1 = null, compare2 = null;
function cancelCompare () {
    $("#filter-detail-table").removeClass("select-compare1");
    $("#filter-detail-table").removeClass("select-compare2");
    $("#filter-detail-table").removeClass("select-compare3");
    $("#filter-detail-table tr").removeClass("selected-1");
    $("#filter-detail-table tr").removeClass("selected-2");
    $("#filter-detail-table tr").unbind("click");
    $("#filter-detail-table tr").unbind("hover");
    $("#filter-detail-table tr").each(removeCheckbox);
    $("#first-prompt").hide();
    $("#second-prompt").hide();
    $("#third-prompt").hide();
    $("#compare-button").button({label:"Compare builds"});
    compareState = 0;
}
function startCompare () {
    $("#compare-button").button({label:"Cancel"});
    $("#filter-detail-table").addClass("select-compare1");
    $("#filter-detail-table tr").click(rowClickHandler);
    $("#filter-detail-table tr").each(insertCheckbox);
    $("#filter-detail-table tr").hover(rowHoverHandlerIn, rowHoverHandlerOut);
    $("#first-prompt").show();
    compareState = 1;
}
function tagFromRow(tr) {
    var firstCell = $(tr).find("td:eq(0)");
    return {
        machinetag: firstCell.find("span").data("machinetag"),
        usertag: firstCell.text()
    };
}
function rowClickHandler() {
    if (compareState == 1) {
        compare1 = tagFromRow($(this));
        $(this).addClass("selected-1");
        $(this).find("input").attr("checked", true);
        $("#p2-build").text(compare1.usertag);
        $("#first-prompt").hide();
        $("#second-prompt").show();
        $("#filter-detail-table").removeClass("select-compare1");
        $("#filter-detail-table").addClass("select-compare2");
        compareState = 2;
    } else if (compareState == 2) {
        var thistag = tagFromRow($(this));
        if (compare1.machinetag == thistag.machinetag) {
            cancelCompare();
            startCompare();
        } else {
            compare2 = thistag;
            $(this).find("input").attr("checked", true);
            $(this).addClass("selected-2");
            $("#second-prompt").hide();
            $("#third-prompt").show();
            $("#filter-detail-table").removeClass("select-compare2");
            $("#filter-detail-table").addClass("select-compare3");
            $("#filter-detail-table input").attr("disabled", true);
            $("#filter-detail-table .selected-1 input").attr("disabled", false);
            $("#filter-detail-table .selected-2 input").attr("disabled", false);
            $("#p3-build-1").text(compare1.usertag);
            $("#p3-build-2").text(compare2.usertag);
            $("#third-prompt a").attr("href", window.location.pathname + '/+compare/' + compare1.machinetag + '/' + compare2.machinetag);
            compareState = 3;
        }
    } else if (compareState == 3) {
        var thistag = tagFromRow($(this));
        if (thistag.machinetag == compare1.machinetag || thistag.machinetag == compare2.machinetag) {
            $("#second-prompt").show();
            $("#third-prompt").hide();
            $("#filter-detail-table").addClass("select-compare2");
            $("#filter-detail-table").removeClass("select-compare3");
            $("#filter-detail-table input").attr("disabled", false);
            compareState = 2;
            $(this).find("input").attr("checked", false);
            if (thistag.machinetag == compare1.machinetag) {
                compare1 = compare2;
                $("#filter-detail-table .selected-1").removeClass("selected-1");
                $("#filter-detail-table .selected-2").addClass("selected-1");
                $("#p2-build").text(compare1.usertag);
            }
            $("#filter-detail-table .selected-2").removeClass("selected-2");
        }
    }
    tagFromRow(this);
}
function rowHoverHandlerIn() {
    $(this).addClass("hover");
}
function rowHoverHandlerOut() {
    $(this).removeClass("hover");
}
function insertCheckbox() {
    var row = $(this);
    var checkbox = $('<input type="checkbox">');
    row.find("td:first").prepend(checkbox);
}
function removeCheckbox() {
    var row = $(this);
    row.find('input').remove();
}
$(window).load(
    function () {
        $("#compare-button").button();
        $("#compare-button").click(
            function (e) {
                if (compareState == 0) {
                    startCompare();
                } else {
                    cancelCompare();
                }
            }
        );
        $("div.dataTables_length").remove();
        $("div.dataTables_info").remove();
        $("div.dataTables_filter").remove();
    }

);
<|endoftext|>


<commit_before>var semver = Npm.require('semver');

ConstraintSolver = {};

// catalog is a catalog.Catalog object. We have to pass this in because
// we're in a package and can't require('release.js'). If this code
// moves to the tool, or if all of the tool code moves to a star, we
// should get cat from release.current.catalog rather than passing it
// in.
ConstraintSolver.PackagesResolver = function (catalog, options) {
  var self = this;

  options = options || {};

  self.catalog = catalog;

  // The main resolver
  self.resolver = new ConstraintSolver.Resolver();

  // XXX for now we convert builds to unit versions as "deps#os"

  var forEveryVersion = function (iter) {
    _.each(catalog.getAllPackageNames(), function (packageName) {
      _.each(catalog.getSortedVersions(packageName), function (version) {
        var versionDef = catalog.getVersion(packageName, version);
        iter(packageName, version, versionDef);
      });
    });
  };

  // Create a unit version for every package
  // Set constraints and dependencies between units
  forEveryVersion(function (packageName, version, versionDef) {
    var builds = {};
    _.each(versionDef.dependencies, function (dep, depName) {
      _.each(dep.references, function (ref) {
        var unitName = packageName + "#" + ref.arch;
        var unitVersion = builds[unitName];
        if (! unitVersion) {
          // if it is first time we met the build of this version, register it
          // in resolver.
          builds[unitName] = new ConstraintSolver.UnitVersion(
            unitName, version, versionDef.earliestCompatibleVersion);
          unitVersion = builds[unitName];
          self.resolver.addUnitVersion(unitVersion);
        }

        var targetUnitName = depName + "#" + ref.arch;

        // Add the dependency if needed
        if (! ref.weak)
          unitVersion.addDependency(targetUnitName);

        // Add a constraint if such exists
        if (dep.constraint && dep.constraint !== "none") {
          var constraint =
            self.resolver.getConstraint(targetUnitName, dep.constraint);
          unitVersion.addConstraint(constraint);
        }
      });
    });

    if (_.isEmpty(builds)) {
      // XXX this is a hack to temporary solve the problem with packages w/o
      // dependencies. Right now in order to understand what are builds of
      // package, we look into its dependencies build-wise. W/o dependencies we
      // would need to do something else, like see what builds other builds
      // depend on. Also if depending builds of other packages don't specify the
      // version, there is no way we can resolve what builds different versions
      // have as different versions of the same package can in theory have
      // diverging sets of builds.
      //
      // But in practive we always have main + os builds. So we
      // will just hardcode two most improtant builds at the moment. Fix it
      // later.
      _.each(["os", "browser"], function (arch) {
        var unitName = packageName + "#" + arch;
        var unitVersion = builds[unitName];
        if (! unitVersion) {
          builds[unitName] = new ConstraintSolver.UnitVersion(
            unitName, version, versionDef.earliestCompatibleVersion);
          unitVersion = builds[unitName];
          self.resolver.addUnitVersion(unitVersion);
        }
      });
    }

    // Every build implies that if it is picked, other builds are constrained to
    // the same version.
    _.each(builds, function (build, buildName) {
      _.each(builds, function (other, otherBuildName) {
        if (build === other)
          return;

        // Constraint is the exact same version of a build
        var constraintStr = "=" + version;
        var constraint =
          self.resolver.getConstraint(otherBuildName, constraintStr);
        build.addConstraint(constraint);
      });
    });
  });
};

ConstraintSolver.PackagesResolver.prototype.resolve =
  function (dependencies, constraints, options) {
  var self = this;

  check(dependencies, [String]);
  check(constraints, [{ packageName: String, version: String, exact: Boolean }]);

  options = _.defaults(options || {}, {
    _testing: false,
    breaking: false
  });

  options.rootDependencies = _.clone(dependencies);

  if (options.previousSolution) {
    options.previousSolution = _.flatten(_.map(options.previousSolution, function (version, packageName) {
      return _.map(self._buildsForPackage(packageName), function (unitName) {
        return self.resolver.unitsVersions[unitName];
      });
    }));
  }

  var dc = self._splitDepsToConstraints(dependencies, constraints);

  var resolverOptions = self._getResolverOptions(options, dc);

  // XXX resolver.resolve can throw an error, should have error handling with
  // proper error translation.
  var res = self.resolver.resolve(dc.dependencies, dc.constraints, [],
                                  resolverOptions);

  var resultChoices = {};
  _.each(res, function (uv) {
    // Since we don't yet define the interface for a an app to depend only on
    // certain builds of the packages (like only browser builds) and we know
    // that each build weakly depends on other sibling builds of the same
    // version, we can safely output the whole package for each build in the
    // result.
    resultChoices[uv.name.split('#')[0]] = uv.version;
  });

  return resultChoices;
};

ConstraintSolver.PackagesResolver.prototype.propagateExactDeps =
  function (dependencies, constraints) {
  var self = this;

  check(dependencies, [String]);
  check(constraints, [{ packageName: String, version: String, exact: Boolean }]);

  var dc = self._splitDepsToConstraints(dependencies, constraints);

  // XXX resolver.resolve can throw an error, should have error handling with
  // proper error translation.
  var res = self.resolver.resolve(dc.dependencies, dc.constraints, null,
                                  { stopAfterFirstPropagation: true });

  var resultChoices = {};
  _.each(res, function (uv) {
    resultChoices[uv.name.split('#')[0]] = uv.version;
  });

  return resultChoices;
};

// takes dependencies and constraints and rewrites the names from "foo" to
// "foo#os" and "foo#browser"
// XXX right now creates a dependency for every build it can find
ConstraintSolver.PackagesResolver.prototype._splitDepsToConstraints =
  function (inputDeps, inputConstraints) {
  var self = this;
  var dependencies = [];
  var constraints = [];

  _.each(inputDeps, function (packageName) {
    _.each(self._buildsForPackage(packageName), function (buildName) {
      dependencies.push(buildName);
    });
  });

  // XXX hackish code duplication
  _.each(inputConstraints, function (constraint) {
    var constraintStr = (constraint.exact ? "=" : "") + constraint.version;

    _.each(self._buildsForPackage(constraint.packageName), function (buildName) {
      constraints.push(self.resolver.getConstraint(buildName, constraintStr));
    });
  });

  return { dependencies: dependencies, constraints: constraints };
};

ConstraintSolver.PackagesResolver.prototype._buildsForPackage =
  function (packageName) {
  var self = this;
  var buildPrefix = packageName + "#";
  var builds = [];
  // XXX hardcode os and browser
  _.each(["os", "browser"], function (arch) {
    if (self.resolver.unitsVersions[buildPrefix + arch])
      builds.push(buildPrefix + arch);
  });

  if (_.isEmpty(builds))
    throw new Error("Cannot find anything about package -- " + packageName);

  return builds;
};

ConstraintSolver.PackagesResolver.prototype._getResolverOptions =
  function (options, dc) {
  var self = this;

  var semverToNum = function (version) {
    version = version.split("+")[0];
    var v = _.map(version.split('.'), function (x) {
      return parseInt(x);
    });

    return v[0] * 10000 + v[1] * 100 + v[2];
  };

  var resolverOptions = {};

  if (options._testing) {
    resolverOptions.costFunction = function (state) {
      var choices = state.choices;
      return _.reduce(choices, function (sum, uv) {
        return semverToNum(uv.version) + sum;
      }, 0);
    };
  } else {
    // Poorman's enum
    var VMAJOR = 0, MAJOR = 1, MEDIUM = 2, MINOR = 3;
    var rootDeps = options.rootDependencies || [];
    var prevSol = options.previousSolution || [];

    var isRootDep = {};
    var prevSolMapping = {};

    _.each(rootDeps, function (dep) { isRootDep[dep] = true; });
    _.each(prevSol, function (uv) { prevSolMapping[uv.name] = uv; });

    resolverOptions.costFunction = function (state, options) {
      var choices = state.choices;
      var constraints = state.constraints;
      // very major, major, medium, minor costs
      // XXX maybe these can be calculated lazily?
      var cost = [0, 0, 0, 0];

      var minimalConstraint = {};
      constraints.each(function (c) {
        if (! _.has(minimalConstraint, c.name))
          minimalConstraint[c.name] = c.version;
        else if (semver.lt(c.version, minimalConstraint[c.name]))
          minimalConstraint[c.name] = c.version;
      });

      _.each(choices, function (uv) {
        if (_.has(prevSolMapping, uv.name)) {
          // The package was present in the previous solution
          var prev = prevSolMapping[uv.name];
          var versionsDistance =
            semverToNum(uv.version) -
            semverToNum(prev.version);

          var isCompatible =
            semver.gte(prev.version, uv.earliestCompatibleVersion) ||
            semver.gte(uv.version, prev.earliestCompatibleVersion);

          if (isRootDep[uv.name]) {
            // root dependency
            if (versionsDistance < 0 || ! isCompatible) {
              // the new pick is older or is incompatible with the prev. solution
              // i.e. can have breaking changes, prefer not to do this
              // XXX in fact we want to avoid downgrades to the direct
              // dependencies at all cost.
              cost[VMAJOR]++;
            } else {
              // compatible but possibly newer
              // prefer the version closest to the older solution
              cost[MEDIUM] += versionsDistance;
            }
          } else {
            // transitive dependency
            // prefer to have less changed transitive dependencies
            cost[MINOR] += versionsDistance === 0 ? 1 : 0;
          }
        } else {
          var latestDistance =
            semverToNum(self.resolver._latestVersion[uv.name]) -
            semverToNum(uv.version);

          if (isRootDep[uv.name]) {
            // root dependency
            // preferably latest
            cost[MAJOR] += latestDistance;
          } else {
            // transitive dependency
            // prefarable earliest possible to be conservative
            cost[MINOR] += semverToNum(uv.version) -
              semverToNum(minimalConstraint[uv.name] || "0.0.0");
          }
        }
      });

      return cost;
    };

    resolverOptions.estimateCostFunction = function (state, options) {
      var dependencies = state.dependencies;
      var constraints = state.constraints;

      var cost = [0, 0, 0, 0];
      return cost;

      dependencies.each(function (dep) {
        if (_.has(prevSolMapping, dep)) {
          // was used in previous solution
          // XXX do something smart here
        } else {
          var versions = self.resolver.unitsVersions[dep];
          var latestFitting = null;

          for (var i = versions.length - 1; i >= 0; i--) {
            if (_.isEmpty(constraints.violatedConstraints(versions[i]))) {
              latestFitting = versions[i];
              break;
            }
          }

          if (! latestFitting) {
            cost[MAJOR] = Infinity;
            return;
          }

          var latestDistance =
            semverToNum(self.resolver._latestVersion[dep]) -
            semverToNum(latestFitting.version);

          if (isRootDep[dep]) {
            cost[MAJOR] += latestDistance;
          } else {
            // one of the transitive dependencies
            // XXX should really be a distance from the earlies fitting
            cost[MINOR] += latestDistance;
          }
        }
      });

      return cost;
    };

    resolverOptions.combineCostFunction = function (costA, costB) {
      if (costA.length !== costB.length)
        throw new Error("Different cost types");

      var arr = [];
      _.each(costA, function (l, i) {
        arr.push(l + costB[i]);
      });

      return arr;
    };
  }

  return resolverOptions;
};
<commit_msg>Fix the way Constraint Solver discovers previous solution<commit_after>var semver = Npm.require('semver');

ConstraintSolver = {};

// catalog is a catalog.Catalog object. We have to pass this in because
// we're in a package and can't require('release.js'). If this code
// moves to the tool, or if all of the tool code moves to a star, we
// should get cat from release.current.catalog rather than passing it
// in.
ConstraintSolver.PackagesResolver = function (catalog, options) {
  var self = this;

  options = options || {};

  self.catalog = catalog;

  // The main resolver
  self.resolver = new ConstraintSolver.Resolver();

  // XXX for now we convert builds to unit versions as "deps#os"

  var forEveryVersion = function (iter) {
    _.each(catalog.getAllPackageNames(), function (packageName) {
      _.each(catalog.getSortedVersions(packageName), function (version) {
        var versionDef = catalog.getVersion(packageName, version);
        iter(packageName, version, versionDef);
      });
    });
  };

  // Create a unit version for every package
  // Set constraints and dependencies between units
  forEveryVersion(function (packageName, version, versionDef) {
    var builds = {};
    _.each(versionDef.dependencies, function (dep, depName) {
      _.each(dep.references, function (ref) {
        var unitName = packageName + "#" + ref.arch;
        var unitVersion = builds[unitName];
        if (! unitVersion) {
          // if it is first time we met the build of this version, register it
          // in resolver.
          builds[unitName] = new ConstraintSolver.UnitVersion(
            unitName, version, versionDef.earliestCompatibleVersion);
          unitVersion = builds[unitName];
          self.resolver.addUnitVersion(unitVersion);
        }

        var targetUnitName = depName + "#" + ref.arch;

        // Add the dependency if needed
        if (! ref.weak)
          unitVersion.addDependency(targetUnitName);

        // Add a constraint if such exists
        if (dep.constraint && dep.constraint !== "none") {
          var constraint =
            self.resolver.getConstraint(targetUnitName, dep.constraint);
          unitVersion.addConstraint(constraint);
        }
      });
    });

    if (_.isEmpty(builds)) {
      // XXX this is a hack to temporary solve the problem with packages w/o
      // dependencies. Right now in order to understand what are builds of
      // package, we look into its dependencies build-wise. W/o dependencies we
      // would need to do something else, like see what builds other builds
      // depend on. Also if depending builds of other packages don't specify the
      // version, there is no way we can resolve what builds different versions
      // have as different versions of the same package can in theory have
      // diverging sets of builds.
      //
      // But in practive we always have main + os builds. So we
      // will just hardcode two most improtant builds at the moment. Fix it
      // later.
      _.each(["os", "browser"], function (arch) {
        var unitName = packageName + "#" + arch;
        var unitVersion = builds[unitName];
        if (! unitVersion) {
          builds[unitName] = new ConstraintSolver.UnitVersion(
            unitName, version, versionDef.earliestCompatibleVersion);
          unitVersion = builds[unitName];
          self.resolver.addUnitVersion(unitVersion);
        }
      });
    }

    // Every build implies that if it is picked, other builds are constrained to
    // the same version.
    _.each(builds, function (build, buildName) {
      _.each(builds, function (other, otherBuildName) {
        if (build === other)
          return;

        // Constraint is the exact same version of a build
        var constraintStr = "=" + version;
        var constraint =
          self.resolver.getConstraint(otherBuildName, constraintStr);
        build.addConstraint(constraint);
      });
    });
  });
};

ConstraintSolver.PackagesResolver.prototype.resolve =
  function (dependencies, constraints, options) {
  var self = this;

  check(dependencies, [String]);
  check(constraints, [{ packageName: String, version: String, exact: Boolean }]);

  options = _.defaults(options || {}, {
    _testing: false,
    breaking: false
  });

  options.rootDependencies = _.clone(dependencies);

  if (options.previousSolution) {
    options.previousSolution = _.flatten(_.map(options.previousSolution, function (version, packageName) {
      return _.map(self._buildsForPackage(packageName), function (unitName) {
        if (!self.resolver._unitsVersionsMap[unitName + "@" + version])
          console.log(unitName, version)
        return self.resolver._unitsVersionsMap[unitName + "@" + version];
      });
    }));
  }

  var dc = self._splitDepsToConstraints(dependencies, constraints);

  var resolverOptions = self._getResolverOptions(options, dc);

  // XXX resolver.resolve can throw an error, should have error handling with
  // proper error translation.
  var res = self.resolver.resolve(dc.dependencies, dc.constraints, [],
                                  resolverOptions);

  var resultChoices = {};
  _.each(res, function (uv) {
    // Since we don't yet define the interface for a an app to depend only on
    // certain builds of the packages (like only browser builds) and we know
    // that each build weakly depends on other sibling builds of the same
    // version, we can safely output the whole package for each build in the
    // result.
    resultChoices[uv.name.split('#')[0]] = uv.version;
  });

  return resultChoices;
};

ConstraintSolver.PackagesResolver.prototype.propagateExactDeps =
  function (dependencies, constraints) {
  var self = this;

  check(dependencies, [String]);
  check(constraints, [{ packageName: String, version: String, exact: Boolean }]);

  var dc = self._splitDepsToConstraints(dependencies, constraints);

  // XXX resolver.resolve can throw an error, should have error handling with
  // proper error translation.
  var res = self.resolver.resolve(dc.dependencies, dc.constraints, null,
                                  { stopAfterFirstPropagation: true });

  var resultChoices = {};
  _.each(res, function (uv) {
    resultChoices[uv.name.split('#')[0]] = uv.version;
  });

  return resultChoices;
};

// takes dependencies and constraints and rewrites the names from "foo" to
// "foo#os" and "foo#browser"
// XXX right now creates a dependency for every build it can find
ConstraintSolver.PackagesResolver.prototype._splitDepsToConstraints =
  function (inputDeps, inputConstraints) {
  var self = this;
  var dependencies = [];
  var constraints = [];

  _.each(inputDeps, function (packageName) {
    _.each(self._buildsForPackage(packageName), function (buildName) {
      dependencies.push(buildName);
    });
  });

  // XXX hackish code duplication
  _.each(inputConstraints, function (constraint) {
    var constraintStr = (constraint.exact ? "=" : "") + constraint.version;

    _.each(self._buildsForPackage(constraint.packageName), function (buildName) {
      constraints.push(self.resolver.getConstraint(buildName, constraintStr));
    });
  });

  return { dependencies: dependencies, constraints: constraints };
};

ConstraintSolver.PackagesResolver.prototype._buildsForPackage =
  function (packageName) {
  var self = this;
  var buildPrefix = packageName + "#";
  var builds = [];
  // XXX hardcode os and browser
  _.each(["os", "browser"], function (arch) {
    if (self.resolver.unitsVersions[buildPrefix + arch])
      builds.push(buildPrefix + arch);
  });

  if (_.isEmpty(builds))
    throw new Error("Cannot find anything about package -- " + packageName);

  return builds;
};

ConstraintSolver.PackagesResolver.prototype._getResolverOptions =
  function (options, dc) {
  var self = this;

  var semverToNum = function (version) {
    version = version.split("+")[0];
    var v = _.map(version.split('.'), function (x) {
      return parseInt(x);
    });

    return v[0] * 10000 + v[1] * 100 + v[2];
  };

  var resolverOptions = {};

  if (options._testing) {
    resolverOptions.costFunction = function (state) {
      var choices = state.choices;
      return _.reduce(choices, function (sum, uv) {
        return semverToNum(uv.version) + sum;
      }, 0);
    };
  } else {
    // Poorman's enum
    var VMAJOR = 0, MAJOR = 1, MEDIUM = 2, MINOR = 3;
    var rootDeps = options.rootDependencies || [];
    var prevSol = options.previousSolution || [];

    var isRootDep = {};
    var prevSolMapping = {};

    _.each(rootDeps, function (dep) { isRootDep[dep] = true; });
    _.each(prevSol, function (uv) { prevSolMapping[uv.name] = uv; });

    resolverOptions.costFunction = function (state, options) {
      var choices = state.choices;
      var constraints = state.constraints;
      // very major, major, medium, minor costs
      // XXX maybe these can be calculated lazily?
      var cost = [0, 0, 0, 0];

      var minimalConstraint = {};
      constraints.each(function (c) {
        if (! _.has(minimalConstraint, c.name))
          minimalConstraint[c.name] = c.version;
        else if (semver.lt(c.version, minimalConstraint[c.name]))
          minimalConstraint[c.name] = c.version;
      });

      _.each(choices, function (uv) {
        if (_.has(prevSolMapping, uv.name)) {
          // The package was present in the previous solution
          var prev = prevSolMapping[uv.name];
          var versionsDistance =
            semverToNum(uv.version) -
            semverToNum(prev.version);

          var isCompatible =
            semver.gte(prev.version, uv.earliestCompatibleVersion) ||
            semver.gte(uv.version, prev.earliestCompatibleVersion);

          if (isRootDep[uv.name]) {
            // root dependency
            if (versionsDistance < 0 || ! isCompatible) {
              // the new pick is older or is incompatible with the prev. solution
              // i.e. can have breaking changes, prefer not to do this
              // XXX in fact we want to avoid downgrades to the direct
              // dependencies at all cost.
              cost[VMAJOR]++;
            } else {
              // compatible but possibly newer
              // prefer the version closest to the older solution
              cost[MEDIUM] += versionsDistance;
            }
          } else {
            // transitive dependency
            // prefer to have less changed transitive dependencies
            cost[MINOR] += versionsDistance === 0 ? 1 : 0;
          }
        } else {
          var latestDistance =
            semverToNum(self.resolver._latestVersion[uv.name]) -
            semverToNum(uv.version);

          if (isRootDep[uv.name]) {
            // root dependency
            // preferably latest
            cost[MAJOR] += latestDistance;
          } else {
            // transitive dependency
            // prefarable earliest possible to be conservative
            cost[MINOR] += semverToNum(uv.version) -
              semverToNum(minimalConstraint[uv.name] || "0.0.0");
          }
        }
      });

      return cost;
    };

    resolverOptions.estimateCostFunction = function (state, options) {
      var dependencies = state.dependencies;
      var constraints = state.constraints;

      var cost = [0, 0, 0, 0];
      return cost;

      dependencies.each(function (dep) {
        if (_.has(prevSolMapping, dep)) {
          // was used in previous solution
          // XXX do something smart here
        } else {
          var versions = self.resolver.unitsVersions[dep];
          var latestFitting = null;

          for (var i = versions.length - 1; i >= 0; i--) {
            if (_.isEmpty(constraints.violatedConstraints(versions[i]))) {
              latestFitting = versions[i];
              break;
            }
          }

          if (! latestFitting) {
            cost[MAJOR] = Infinity;
            return;
          }

          var latestDistance =
            semverToNum(self.resolver._latestVersion[dep]) -
            semverToNum(latestFitting.version);

          if (isRootDep[dep]) {
            cost[MAJOR] += latestDistance;
          } else {
            // one of the transitive dependencies
            // XXX should really be a distance from the earlies fitting
            cost[MINOR] += latestDistance;
          }
        }
      });

      return cost;
    };

    resolverOptions.combineCostFunction = function (costA, costB) {
      if (costA.length !== costB.length)
        throw new Error("Different cost types");

      var arr = [];
      _.each(costA, function (l, i) {
        arr.push(l + costB[i]);
      });

      return arr;
    };
  }

  return resolverOptions;
};
<|endoftext|>


<commit_before>/*jshint expr: true*/
"use strict";
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
var mockHelper = require("./helpers/mock_helper");
chai.use(chaiAsPromised);
var expect = chai.expect;
chai.config.includeStack = true;

describe("Alexa", function() {
  var Alexa = require("../index");
  describe("app", function() {
    var app = new Alexa.app("myapp");
    describe("#request", function() {
      describe("response", function() {
        var mockRequest = mockHelper.load("intent_request_airport_info.json");
        describe("defaults", function() {
          var subject = app.request(mockRequest);
          it("responds with expected version attribute", function() {
            return expect(subject).to.eventually.have.property("version", "1.0");
          });
          describe("alexa response", function() {
            it("responds with expected alexa response defaults", function() {
              subject = subject.then(function(response) {
                return response.response;
              });
              return expect(subject).to.eventually.have.property("shouldEndSession", true);
            });
          });
        });
        context("with an intent request of airportInfoIntent", function() {
          context("with no intent handler", function() {
            var app = new Alexa.app("myapp");
            var subject = app.request(mockRequest);
            describe("outputSpeech", function() {
              subject = subject.then(function(response) {
                return response.response.outputSpeech;
              });
              it("responds with NO_INTENT_FOUND message", function() {
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + app.messages.NO_INTENT_FOUND + "</speak>",
                  type: "SSML"
                });
              });
            });
          });

          context("with a matching intent handler", function() {
            var app = new Alexa.app("myapp");
            var intentHandler = function(req, res) {
              res.say(expectedMessage);
              return true;
            };
            var expectedMessage = "tubular!";
            app.intent("airportInfoIntent", {}, intentHandler);

            describe("outputSpeech", function() {
              it("combines says into a larger response", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage).say(expectedMessage);
                  return true;
                };
                app.intent("airportInfoIntent", {}, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + expectedMessage + " " + expectedMessage + "</speak>",
                  type: "SSML"
                });
              });
              it("responds with expected message", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage);
                  return true;
                };
                app.intent("airportInfoIntent", { }, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + expectedMessage + "</speak>",
                  type: "SSML"
                });
              });
            });
          });
        });
      });
    });
  });
});
<commit_msg>adds clear test<commit_after>/*jshint expr: true*/
"use strict";
var chai = require("chai");
var chaiAsPromised = require("chai-as-promised");
var mockHelper = require("./helpers/mock_helper");
chai.use(chaiAsPromised);
var expect = chai.expect;
chai.config.includeStack = true;

describe("Alexa", function() {
  var Alexa = require("../index");
  describe("app", function() {
    var app = new Alexa.app("myapp");
    describe("#request", function() {
      describe("response", function() {
        var mockRequest = mockHelper.load("intent_request_airport_info.json");
        describe("defaults", function() {
          var subject = app.request(mockRequest);
          it("responds with expected version attribute", function() {
            return expect(subject).to.eventually.have.property("version", "1.0");
          });
          describe("alexa response", function() {
            it("responds with expected alexa response defaults", function() {
              subject = subject.then(function(response) {
                return response.response;
              });
              return expect(subject).to.eventually.have.property("shouldEndSession", true);
            });
          });
        });
        context("with an intent request of airportInfoIntent", function() {
          context("with no intent handler", function() {
            var app = new Alexa.app("myapp");
            var subject = app.request(mockRequest);
            describe("outputSpeech", function() {
              subject = subject.then(function(response) {
                return response.response.outputSpeech;
              });
              it("responds with NO_INTENT_FOUND message", function() {
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + app.messages.NO_INTENT_FOUND + "</speak>",
                  type: "SSML"
                });
              });
            });
          });

          context("with a matching intent handler", function() {
            var app = new Alexa.app("myapp");
            var intentHandler = function(req, res) {
              res.say(expectedMessage);
              return true;
            };
            var expectedMessage = "tubular!";
            app.intent("airportInfoIntent", {}, intentHandler);

            describe("outputSpeech", function() {
              it("clears output when clear is called", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage).say(expectedMessage).clear();
                  return true;
                };
                app.intent("airportInfoIntent", {}, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                return expect(subject).to.eventually.become({
                  text: "",
                  type: "PlainText"
                });
              });
              it("clears output when clear is called and say is then called", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage)
                    .say(expectedMessage)
                    .clear().say(expectedMessage);
                  return true;
                };
                app.intent("airportInfoIntent", {}, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                //this seems like a strange result - should type be ssml? looks like a bug
                return expect(subject).to.eventually.become({
                  ssml: "<speak>tubular!</speak>",
                  text: "",
                  type: "PlainText"
                });
              });

              it("combines says into a larger response", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage).say(expectedMessage);
                  return true;
                };
                app.intent("airportInfoIntent", {}, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + expectedMessage + " " + expectedMessage + "</speak>",
                  type: "SSML"
                });
              });
              it("responds with expected message", function() {
                app = new Alexa.app("myapp");
                intentHandler = function(req, res) {
                  res.say(expectedMessage);
                  return true;
                };
                app.intent("airportInfoIntent", { }, intentHandler);
                var subject = app.request(mockRequest);
                subject = subject.then(function(response) {
                  return response.response.outputSpeech;
                });
                return expect(subject).to.eventually.become({
                  ssml: "<speak>" + expectedMessage + "</speak>",
                  type: "SSML"
                });
              });
            });
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>/*! Pickyfill - Offline caching for picturefill responsive image polyfill. Author: Rich Trott | Copyright: Regents of University of California, 2012 | License: MIT */

(function( w ) {
    "use strict";

    var localStorage = w.localStorage,
        applicationCache = w.applicationCache,
        image,
        imageSrc,
        dataUri,
        pf_index_string,
        pf_index,
        canvasTest = document.createElement('canvas');

    // Don't run any of this stuff if application cache doesn't exist or isn't being used,
    //     or localStorage or canvas are not available.
    if ( (! applicationCache) || (applicationCache.status === applicationCache.UNCACHED) ||
        (! localStorage) || (!(canvasTest.getContext && canvasTest.getContext('2d'))) ) {
            return;
    }

    pf_index_string = localStorage.getItem('pf_index') || '{}';
    pf_index = JSON.parse(pf_index_string);

    // We'll use this to clear the pickyfill cache when appcache updates.
    var clearCache = function () {
        localStorage.removeItem('pf_index');
        for (var prop in pf_index) {
            localStorage.removeItem(prop);
        }
    };

    // Unfortunately, reloading is the most reliable way to get stuff into the
    //  pickyfill cache. If you wait for the user to reload, they may be offline
    //  at that time. If we just had an updateready event, chances are very good
    //  that they are still online. Another possibility is to just try to reload
    //  the images that are currently shown, but there's no guarantee that those
    //  images are in the new page or that the current page isn't missing important
    //  images that will display in the new page and need to be cached.
    var refreshCache = function () {
        clearCache();
        w.location.reload();
    };

    // If appcache updates, refresh the pickyfill cache to get new items.
    // If appcache is obsolete, clear the pickyfill cache.
    // Appcache == IE10 or later == no need to worry about attachEvent (IE8 and earlier)
    // Anything that has appcache is going to have addEventListener.
    applicationCache.addEventListener('updateready', refreshCache, false);
    applicationCache.addEventListener('obsolete', clearCache, false);

    // If the event has already fired and we missed it, clear/refresh the pickyfill cache.
    if(applicationCache.status === applicationCache.UPDATEREADY) {
        refreshCache();
    }

    if (applicationCache.status === applicationCache.OBSOLETE) {
        clearCache();
    }

    var srcFromCacheRan = false;
    var srcFromCache = function ( ps ) {
        var sources, src, newSrc;

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                sources = ps[ i ].getElementsByTagName( "div" );
                // See which ones are cached in localStorage. Use the cached value.
                for( var j = 0, jl = sources.length; j < jl; j++ ){
                    if ((src = sources[j].getAttribute( "data-src" )) !== null ) {
                        if ( pf_index.hasOwnProperty('pf_s_' + src)) {
                            newSrc = localStorage.getItem('pf_s_' + src);
                            if (newSrc !== null) {
                                sources[j].setAttribute('data-src', localStorage.getItem('pf_s_' + src));
                            }
                        }
                    }
                }
            }
        }
    };

    var cacheImage = function () {
        var canvas, ctx, imageSrc;

        imageSrc = this.getAttribute("src");
        // Check for "data:" because sometimes it slips through.
        // TODO: Figure out why "someimtes it slips through". (Happens on FF 14.0.1 on Mac at least.)
        if ((imageSrc === null) || (imageSrc.length === 0) || (imageSrc.substr(0,5) === "data:")) {
            return;
        }

        canvas = w.document.createElement("canvas");
        canvas.width = this.width;
        canvas.height = this.height;

        ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);
        try {
            dataUri = canvas.toDataURL();
        } catch (e) {
            // TODO: Improve error handling here. For now, if canvas.toDataURL()
            //   throws an exception, don't cache the image and move on.
            return;
        }

        // Do not cache if the resulting cache item will take more than 128Kb.
        if (dataUri.length > 131072) {
            return;
        }

        pf_index["pf_s_"+imageSrc] = 1;

        try {
            localStorage.setItem("pf_s_"+imageSrc, dataUri);
            localStorage.setItem("pf_index", JSON.stringify(pf_index));
        } catch (e) {
            // Caching failed. Remove item from index object so next cached item
            //   doesn't wrongly indicate this item was successfully cached.
            delete pf_index["pf_s_"+imageSrc];
        }
    };

    w.picturefillOrig = w.picturefill;
    w.picturefill = function () {
        var ps = w.document.getElementsByTagName( "div" );

        if (! srcFromCacheRan ) {
            srcFromCacheRan = true;
            srcFromCache( ps );
        }

        w.picturefillOrig();

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                image = ps[ i ].getElementsByTagName( "img" )[0];
                if (image) {
                    if ((imageSrc = image.getAttribute("src")) !== null) {
                        if (imageSrc.substr(0,5) !== "data:") {
                            image.onload = cacheImage;
                        }
                    }
                }
            }
        }
    };

}( this ));
<commit_msg>Populate localStorage on initial visit<commit_after>/*! Pickyfill - Offline caching for picturefill responsive image polyfill. Author: Rich Trott | Copyright: Regents of University of California, 2012 | License: MIT */

(function( w ) {
    "use strict";

    var localStorage = w.localStorage,
        applicationCache = w.applicationCache,
        image,
        dataUri,
        pf_index_string,
        pf_index,
        canvasTest = document.createElement('canvas');

    // Don't run any of this stuff if application cache doesn't exist or isn't being used,
    //     or localStorage or canvas are not available.
    if ( (! applicationCache) || (applicationCache.status === applicationCache.UNCACHED) ||
        (! localStorage) || (!(canvasTest.getContext && canvasTest.getContext('2d'))) ) {
            return;
    }

    pf_index_string = localStorage.getItem('pf_index') || '{}';
    pf_index = JSON.parse(pf_index_string);

    // We'll use this to clear the pickyfill cache when appcache updates.
    var clearCache = function () {
        localStorage.removeItem('pf_index');
        for (var prop in pf_index) {
            localStorage.removeItem(prop);
        }
    };

    // Unfortunately, reloading is the most reliable way to get stuff into the
    //  pickyfill cache. If you wait for the user to reload, they may be offline
    //  at that time. If we just had an updateready event, chances are very good
    //  that they are still online. Another possibility is to just try to reload
    //  the images that are currently shown, but there's no guarantee that those
    //  images are in the new page or that the current page isn't missing important
    //  images that will display in the new page and need to be cached.
    var refreshCache = function () {
        clearCache();
        w.location.reload();
    };

    // If appcache updates, refresh the pickyfill cache to get new items.
    // If appcache is obsolete, clear the pickyfill cache.
    // Appcache == IE10 or later == no need to worry about attachEvent (IE8 and earlier)
    // Anything that has appcache is going to have addEventListener.
    applicationCache.addEventListener('updateready', refreshCache, false);
    applicationCache.addEventListener('obsolete', clearCache, false);

    // If the event has already fired and we missed it, clear/refresh the pickyfill cache.
    if(applicationCache.status === applicationCache.UPDATEREADY) {
        refreshCache();
    }

    if (applicationCache.status === applicationCache.OBSOLETE) {
        clearCache();
    }

    var srcFromCacheRan = false;
    var srcFromCache = function ( ps ) {
        var sources, src, newSrc;

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){

                sources = ps[ i ].getElementsByTagName( "div" );
                // See which ones are cached in localStorage. Use the cached value.
                for( var j = 0, jl = sources.length; j < jl; j++ ){
                    if ((src = sources[j].getAttribute( "data-src" )) !== null ) {
                        if ( pf_index.hasOwnProperty('pf_s_' + src)) {
                            newSrc = localStorage.getItem('pf_s_' + src);
                            if (newSrc !== null) {
                                sources[j].setAttribute('data-src', localStorage.getItem('pf_s_' + src));
                            }
                        }
                    }
                }
            }
        }
    };

    var cacheImage = function ( param ) {
        var canvas,
            ctx,
            imageSrc,
            me;

        me = param.target ? param.target : param;

        // Firefox, at least FF 14 on the Mac, can trigger a load event on the element
        // before the iamge is actually done loading. This is less than great.
        if ((! me.complete) && ((typeof me.readyState === "undefined") || (me.readyState !== 4))) {
            // Could do a setTimeout() or something to try again. But for now, let's just
            // see how well we get by without those kinds of shenanigans.
            return;
        }

        imageSrc = me.getAttribute("src");
        if ((imageSrc === null) || (imageSrc.length === 0) || (imageSrc.substr(0,5) === "data:")) {
            return;
        }

        canvas = w.document.createElement("canvas");
        canvas.width = me.width;
        canvas.height = me.height;

        ctx = canvas.getContext("2d");
        ctx.drawImage(me, 0, 0);
        try {
            dataUri = canvas.toDataURL();
        } catch (e) {
            // TODO: Improve error handling here. For now, if canvas.toDataURL()
            //   throws an exception, don't cache the image and move on.
            return;
        }

        // Do not cache if the resulting cache item will take more than 128Kb.
        if (dataUri.length > 131072) {
            return;
        }

        pf_index["pf_s_"+imageSrc] = 1;

        try {
            localStorage.setItem("pf_s_"+imageSrc, dataUri);
            localStorage.setItem("pf_index", JSON.stringify(pf_index));
        } catch (e) {
            // Caching failed. Remove item from index object so next cached item
            //   doesn't wrongly indicate this item was successfully cached.
            delete pf_index["pf_s_"+imageSrc];
        }
    };

    w.picturefillOrig = w.picturefill;
    w.picturefill = function () {
        var ps = w.document.getElementsByTagName( "div" );

        if (! srcFromCacheRan ) {
            srcFromCacheRan = true;
            srcFromCache( ps );
        }

        w.picturefillOrig();

        // Loop the pictures
        for( var i = 0, il = ps.length; i < il; i++ ){
            if( ps[ i ].getAttribute( "data-picture" ) !== null ){
                image = ps[ i ].getElementsByTagName( "img" )[0];
                if (image) {
                    if (image.getAttribute("src") !== null) {
                        image.onload = cacheImage;
                        if (image.complete || image.readyState === 4) {
                            cacheImage(image);
                        }
                    }
                }
            }
        }
    };

}( this ));
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedNumber, FormattedMessage } from 'react-intl';
import { imagePreview, capitalize } from '../lib/utils';
import { pickAvatar } from '../lib/user.lib';
import { get } from 'lodash';
import TransactionDetails from './TransactionDetails';

class Transaction extends React.Component {

  static propTypes = {
    collective: PropTypes.object,
    transaction: PropTypes.object
  }

  constructor(props) {
    super(props);
    this.state = { view: 'compact' };
    this.toggleDetails = this.toggleDetails.bind(this);
    this.messages = defineMessages({
      'expense': { id: 'transaction.expense', defaultMessage: 'expense' },
      'donation': { id: 'transaction.donation', defaultMessage: 'donation' },
      'donation.title': { id: 'transaction.donation.title', defaultMessage: '{interval, select, month {monthly} year {yearly} other {}} donation to {collective}' },
      'expense.meta': { id: 'transaction.expense.meta', defaultMessage: 'Expense submitted by {name}, paid on {createdAt, date, medium}' },
      'donation.meta': { id: 'transaction.donation.meta', defaultMessage: 'Donation made by {name} on {createdAt, date, medium}' },
      'closeDetails': { id: 'transaction.closeDetails', defaultMessage: 'Close Details' },
      'viewDetails': { id: 'transaction.viewDetails', defaultMessage: 'View Details' }
    });
    this.currencyStyle = { style: 'currency', currencyDisplay: 'symbol', minimumFractionDigits: 0, maximumFractionDigits: 2};
  }

  toggleDetails() {
    this.setState({loadDetails: true, view: this.state.view === 'details' ? 'compact' : 'details'})
  }

  render() {
    const { intl, collective, transaction } = this.props;

    const type = transaction.type.toLowerCase();

    const meta = [];
    meta.push(transaction.category);
    meta.push(intl.formatMessage(this.messages[`${type}.meta`], { name: transaction.user.name, createdAt: new Date(transaction.createdAt) }));

    return (
      <div className={`transaction ${type} ${this.state.view}View`}>

          <FormattedNumber
            value={transaction.amount / 100}
            currency={transaction.currency}
            {...this.currencyStyle}
            />

          <a href={`/${transaction.user.username}`} title={transaction.user.name}>

        {/* should link to `/${collective.slug}/transactions/${transaction.uuid}` once we have a page for it */}
          {type === 'expense' && transaction.title}
          {type === 'donation' && capitalize(intl.formatMessage(this.messages['donation.title'], {collective: collective.name, interval: get(transaction, 'subscription.interval')}))}

            {capitalize(meta.join(' '))}
             | {intl.formatMessage(this.messages[`${this.state.view === 'details' ? 'closeDetails' : 'viewDetails'}`])}

          {this.state.loadDetails && <TransactionDetails transaction={transaction} collective={collective} mode={this.state.view === 'details' ? 'open' : 'closed'} />}

    );
  }
}

export default injectIntl(Transaction);<commit_msg>Show the custom title for donations if any<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedNumber, FormattedMessage } from 'react-intl';
import { imagePreview, capitalize } from '../lib/utils';
import { pickAvatar } from '../lib/user.lib';
import { get } from 'lodash';
import TransactionDetails from './TransactionDetails';

class Transaction extends React.Component {

  static propTypes = {
    collective: PropTypes.object,
    transaction: PropTypes.object
  }

  constructor(props) {
    super(props);
    this.state = { view: 'compact' };
    this.toggleDetails = this.toggleDetails.bind(this);
    this.messages = defineMessages({
      'expense': { id: 'transaction.expense', defaultMessage: 'expense' },
      'donation': { id: 'transaction.donation', defaultMessage: 'donation' },
      'donation.title': { id: 'transaction.donation.title', defaultMessage: '{interval, select, month {monthly} year {yearly} other {}} donation to {collective}' },
      'expense.meta': { id: 'transaction.expense.meta', defaultMessage: 'Expense submitted by {name}, paid on {createdAt, date, medium}' },
      'donation.meta': { id: 'transaction.donation.meta', defaultMessage: 'Donation made by {name} on {createdAt, date, medium}' },
      'closeDetails': { id: 'transaction.closeDetails', defaultMessage: 'Close Details' },
      'viewDetails': { id: 'transaction.viewDetails', defaultMessage: 'View Details' }
    });
    this.currencyStyle = { style: 'currency', currencyDisplay: 'symbol', minimumFractionDigits: 0, maximumFractionDigits: 2};
  }

  toggleDetails() {
    this.setState({loadDetails: true, view: this.state.view === 'details' ? 'compact' : 'details'})
  }

  render() {
    const { intl, collective, transaction } = this.props;

    const type = transaction.type.toLowerCase();

    let title = transaction.title;
    if (type === 'donation' && (!title || title.match(/donation to /i))) {
      title = intl.formatMessage(this.messages['donation.title'], {collective: collective.name, interval: get(transaction, 'subscription.interval')})
    }

    const meta = [];
    meta.push(transaction.category);
    meta.push(intl.formatMessage(this.messages[`${type}.meta`], { name: transaction.user.name, createdAt: new Date(transaction.createdAt) }));

    return (
      <div className={`transaction ${type} ${this.state.view}View`}>

          <FormattedNumber
            value={transaction.amount / 100}
            currency={transaction.currency}
            {...this.currencyStyle}
            />

          <a href={`/${transaction.user.username}`} title={transaction.user.name}>

        {/* should link to `/${collective.slug}/transactions/${transaction.uuid}` once we have a page for it */}
          {capitalize(title)}

            {capitalize(meta.join(' '))}
             | {intl.formatMessage(this.messages[`${this.state.view === 'details' ? 'closeDetails' : 'viewDetails'}`])}

          {this.state.loadDetails && <TransactionDetails transaction={transaction} collective={collective} mode={this.state.view === 'details' ? 'open' : 'closed'} />}

    );
  }
}

export default injectIntl(Transaction);<|endoftext|>


<commit_before>/**
  Compile and combine handlebar templates into one js file.  Then stitch all javascript files
  (including templates) into one js file
*/
var _ = require('underscore');
var path = require('path');
var stitch  = require('stitch');
var fs      = require('fs');
var stylus = require('stylus');
var mkdirp = require('mkdirp');
var async = require('async');
var walk = require('walk');
var stylusHelpers = require('./stylusHelpers');
var jsPackage;
var handlebars = require('handlebars');
var exec = require('child_process').exec;

var baseDir = rendr.entryPath;
var rootDir = path.normalize(__dirname + '/../..');
var publicDir = baseDir + '/../public';
var assetsDir = baseDir + '/../assets';

var config = {
  stitchedJsFile: publicDir + '/mergedAssets.js',
  stylusEntryFile: assetsDir + '/stylesheets/index.styl',
  cssOutputFile: publicDir + '/styles.css',
  fingerprintedImagesDir: publicDir + '/fingerprinted',
  tempDir: rootDir + '/tmp',
  hbsTemplateSrcPath: baseDir + '/templates',
  minify: true
};

/**
  Init and start the template and js compiler.
  options:
  - jsSrcPaths: directory where javascript files are found
  - stitchedJsFile: path and filename of where compiled/combined javascript file will be stored
  - minify: true/false if templates.js should be minified
*/
module.exports.init = function(options, logger, callback) {
  if (options) _.extend(config, options);

  // normalize paths
  var toNormalize = ['stitchedJsFile', 'stylusEntryFile', 'cssOutputFile', 'fingerprintedImagesDir', 'tempDir'];
  for (var i in toNormalize) {
    var key = toNormalize[i];
    config[key] = path.normalize(config[key]);
  }

  // create tmp dir
  if (!fs.existsSync(config.tempDir)) {
    fs.mkdirSync(config.tempDir);
  }
  // this is where the merged template file will live
  // notify stitch to look in tempDir for the js file we will place there
  if (!config.jsSrcPaths) config.jsSrcPaths = [];

  // Before we can create the Stitch package, let's grab the filenames
  // of all non-CommonJS dependencies.
  var walker = walk.walk(assetsDir + '/vendor')
    , vendorFiles = []
    , dependencies
    , i
    , filename
    ;

  // If certain ones need to go first, list them.
  dependencies = [
    'jquery-1.6.2.min.js',
    'underscore-1.4.2.js'
  ];

  walker.on('names', function(root, files){
    for (i in files) {
      filename = root + '/' + files[i];
      // Ignore explicitly-ordered deps.
      if (dependencies.indexOf(files[i]) === -1) {
        // Ignore dirs.
        if (filename.slice(filename.length - 3) === '.js') {
          vendorFiles.push(filename);
        }
      }
    }
  });

  // Full path.
  for (i in dependencies) {
    dependencies[i] = assetsDir + '/vendor/' + dependencies[i];
  }

  walker.on('end', function(){
    // Sort so we always get the same fingerprint on different systems.
    vendorFiles = vendorFiles.sort();

    // init Stitch
    jsPackage = stitch.createPackage({
      paths: config.jsSrcPaths,
      dependencies: dependencies.concat(vendorFiles)
    });
    callback(undefined, "OK")
  });
}

function compileStylus(stylusPath, callback) {
  fs.readFile(stylusPath, function(err, stylusFile) {
    stylus(stylusFile.toString())
      .include(assetsDir + '/stylesheets')
      .set('filename', config.cssOutputFile)
      .set('compress', config.minify)
      .define('asset-url', stylusHelpers.assetUrl())
      .define('image-url', stylusHelpers.assetUrl('images'))
      .render(function(err, css) {
        if (err) return callback(err);
        callback(null, css);
      });
  });
}

var compiledTemplatePrefix = [];
// compiledTemplatePrefix.push("Handlebars = this.window ? window.Handlebars : require('handlebars');");
compiledTemplatePrefix.push("module.exports = Handlebars.templates = {};");
compiledTemplatePrefix.push("\n");

function compileHbs(options, callback) {
  var srcPath = config.hbsTemplateSrcPath;
  var destFile = config.hbsTemplateSrcPath + "/compiledTemplates.js";

  // compile handlebar templates
  // reference handlebars locally vs globally
  var handlebarsCmd = rootDir + '/node_modules/.bin/handlebars'
  exec(handlebarsCmd + ' ' + srcPath + '/*.hbs', function(err, stdout, stderr) {
    if (err) return callback(err);
    // write compiled templates to file
    var data = compiledTemplatePrefix.join("\n") + stdout;
    fs.writeFile(destFile, data, 'utf8', function(err) {
      if (err) return callback(err);
      console.log(destFile + ' created');
      callback();
    });
  });
}

/**
  Compile templates into one js file, then stitch all js into one js file
*/
module.exports.compile = function(callback) {
  async.series([
    function(next){
      compileHbs(undefined, next);
    },
    function(next){
      mkdirp.sync(config.tempDir + '/assetCompiler/rendr');
      exec('cp -R '+rootDir+'/client '+rootDir+'/tmp/assetCompiler/rendr/; cp -R '+rootDir+'/shared '+rootDir+'/tmp/assetCompiler/rendr/', next);
    },
    function(next){
      jsPackage.compile(function (err, source) {
        if (err) return next(err);
        fs.writeFile(config.stitchedJsFile, source, function (err) {
          if (err) return next(err);
          console.log('Compiled ' + config.stitchedJsFile);
          next(null, {js: config.stitchedJsFile});
        });
      });
    },
    function(next){
      compileStylus(config.stylusEntryFile, function(err, css){
        if (err) return next(err);
        fs.writeFile(config.cssOutputFile, css, function (err) {
          if (err) return next(err);
          console.log('Compiled ' + config.cssOutputFile);
          next(null, {css: config.cssOutputFile});
        });
      });
    }
  ], function(err, results){
    if (err) return callback(err);
    var hash = {};
    results.forEach(function(result){
      _.extend(hash, result);
    });
    callback(null, hash);
  });
}

/**
  return path to compiled/combined javascript file
*/
module.exports.stitchedJsFile = function stitchedJsFile() {
  return config.stitchedJsFile;
}
<commit_msg>requiring jQuery 1.8.2 instead of 1.6.2<commit_after>/**
  Compile and combine handlebar templates into one js file.  Then stitch all javascript files
  (including templates) into one js file
*/
var _ = require('underscore');
var path = require('path');
var stitch  = require('stitch');
var fs      = require('fs');
var stylus = require('stylus');
var mkdirp = require('mkdirp');
var async = require('async');
var walk = require('walk');
var stylusHelpers = require('./stylusHelpers');
var jsPackage;
var handlebars = require('handlebars');
var exec = require('child_process').exec;

var baseDir = rendr.entryPath;
var rootDir = path.normalize(__dirname + '/../..');
var publicDir = baseDir + '/../public';
var assetsDir = baseDir + '/../assets';

var config = {
  stitchedJsFile: publicDir + '/mergedAssets.js',
  stylusEntryFile: assetsDir + '/stylesheets/index.styl',
  cssOutputFile: publicDir + '/styles.css',
  fingerprintedImagesDir: publicDir + '/fingerprinted',
  tempDir: rootDir + '/tmp',
  hbsTemplateSrcPath: baseDir + '/templates',
  minify: true
};

/**
  Init and start the template and js compiler.
  options:
  - jsSrcPaths: directory where javascript files are found
  - stitchedJsFile: path and filename of where compiled/combined javascript file will be stored
  - minify: true/false if templates.js should be minified
*/
module.exports.init = function(options, logger, callback) {
  if (options) _.extend(config, options);

  // normalize paths
  var toNormalize = ['stitchedJsFile', 'stylusEntryFile', 'cssOutputFile', 'fingerprintedImagesDir', 'tempDir'];
  for (var i in toNormalize) {
    var key = toNormalize[i];
    config[key] = path.normalize(config[key]);
  }

  // create tmp dir
  if (!fs.existsSync(config.tempDir)) {
    fs.mkdirSync(config.tempDir);
  }
  // this is where the merged template file will live
  // notify stitch to look in tempDir for the js file we will place there
  if (!config.jsSrcPaths) config.jsSrcPaths = [];

  // Before we can create the Stitch package, let's grab the filenames
  // of all non-CommonJS dependencies.
  var walker = walk.walk(assetsDir + '/vendor')
    , vendorFiles = []
    , dependencies
    , i
    , filename
    ;

  // If certain ones need to go first, list them.
  dependencies = [
    'jquery-1.8.2.min.js',
    'underscore-1.4.2.js'
  ];

  walker.on('names', function(root, files){
    for (i in files) {
      filename = root + '/' + files[i];
      // Ignore explicitly-ordered deps.
      if (dependencies.indexOf(files[i]) === -1) {
        // Ignore dirs.
        if (filename.slice(filename.length - 3) === '.js') {
          vendorFiles.push(filename);
        }
      }
    }
  });

  // Full path.
  for (i in dependencies) {
    dependencies[i] = assetsDir + '/vendor/' + dependencies[i];
  }

  walker.on('end', function(){
    // Sort so we always get the same fingerprint on different systems.
    vendorFiles = vendorFiles.sort();

    // init Stitch
    jsPackage = stitch.createPackage({
      paths: config.jsSrcPaths,
      dependencies: dependencies.concat(vendorFiles)
    });
    callback(undefined, "OK")
  });
}

function compileStylus(stylusPath, callback) {
  fs.readFile(stylusPath, function(err, stylusFile) {
    stylus(stylusFile.toString())
      .include(assetsDir + '/stylesheets')
      .set('filename', config.cssOutputFile)
      .set('compress', config.minify)
      .define('asset-url', stylusHelpers.assetUrl())
      .define('image-url', stylusHelpers.assetUrl('images'))
      .render(function(err, css) {
        if (err) return callback(err);
        callback(null, css);
      });
  });
}

var compiledTemplatePrefix = [];
// compiledTemplatePrefix.push("Handlebars = this.window ? window.Handlebars : require('handlebars');");
compiledTemplatePrefix.push("module.exports = Handlebars.templates = {};");
compiledTemplatePrefix.push("\n");

function compileHbs(options, callback) {
  var srcPath = config.hbsTemplateSrcPath;
  var destFile = config.hbsTemplateSrcPath + "/compiledTemplates.js";

  // compile handlebar templates
  // reference handlebars locally vs globally
  var handlebarsCmd = rootDir + '/node_modules/.bin/handlebars'
  exec(handlebarsCmd + ' ' + srcPath + '/*.hbs', function(err, stdout, stderr) {
    if (err) return callback(err);
    // write compiled templates to file
    var data = compiledTemplatePrefix.join("\n") + stdout;
    fs.writeFile(destFile, data, 'utf8', function(err) {
      if (err) return callback(err);
      console.log(destFile + ' created');
      callback();
    });
  });
}

/**
  Compile templates into one js file, then stitch all js into one js file
*/
module.exports.compile = function(callback) {
  async.series([
    function(next){
      compileHbs(undefined, next);
    },
    function(next){
      mkdirp.sync(config.tempDir + '/assetCompiler/rendr');
      exec('cp -R '+rootDir+'/client '+rootDir+'/tmp/assetCompiler/rendr/; cp -R '+rootDir+'/shared '+rootDir+'/tmp/assetCompiler/rendr/', next);
    },
    function(next){
      jsPackage.compile(function (err, source) {
        if (err) return next(err);
        fs.writeFile(config.stitchedJsFile, source, function (err) {
          if (err) return next(err);
          console.log('Compiled ' + config.stitchedJsFile);
          next(null, {js: config.stitchedJsFile});
        });
      });
    },
    function(next){
      compileStylus(config.stylusEntryFile, function(err, css){
        if (err) return next(err);
        fs.writeFile(config.cssOutputFile, css, function (err) {
          if (err) return next(err);
          console.log('Compiled ' + config.cssOutputFile);
          next(null, {css: config.cssOutputFile});
        });
      });
    }
  ], function(err, results){
    if (err) return callback(err);
    var hash = {};
    results.forEach(function(result){
      _.extend(hash, result);
    });
    callback(null, hash);
  });
}

/**
  return path to compiled/combined javascript file
*/
module.exports.stitchedJsFile = function stitchedJsFile() {
  return config.stitchedJsFile;
}
<|endoftext|>


<commit_before>import React from 'react'
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'
import { Divider, Header, Menu, Segment } from 'semantic-ui-react'
import * as accountActions from '../actions/accountActions'
import { Link } from 'react-router-dom'
import Login from '../components/elements/login'

class Sidebar extends React.Component {
  componentDidMount() {
    if (!this.props.account) {
      this.props.actions.fetchAccount()
    }
  }
  render() {
    const forums = this.props.forums;
    let requestForum = (
          <Segment basic textAlign='center'>

              Have an idea for a forum?

              Make a post on the <Link to='/forum/chainbb'>chainBB forum</Link> with what you would like to see or any ideas you may have.

          </Segment>
        )
        ,
        categories = (
          <Menu vertical fluid color='blue' size='small'>
            <Link className={`item ${(!forums || !forums.group) ? 'active' : ''}`} to='/'>
              General Forums
            </Link>
            <Link className={`item ${(forums && forums.group === 'steem') ? 'active' : ''}`} to='/forums/steem'>
              Steem Forums
            </Link>
            <Link className={`item ${(forums && forums.group === 'crypto') ? 'active' : ''}`} to='/forums/crypto'>
              Crypto Forums
            </Link>
            {/*
            <Menu.Item disabled>My Feed</Menu.Item>
            <Menu.Item disabled>Communities</Menu.Item>
            <Menu.Item disabled>Trending</Menu.Item>
            <Menu.Item disabled>New Posts</Menu.Item>
            <Menu.Item disabled>Promoted</Menu.Item>
            <Menu.Item disabled>Tags</Menu.Item>
            */}
          </Menu>
        )

    return (

        <Login {... this.props}/>
        <Divider horizontal>
          Forum Groups
        </Divider>
        {categories}
        <Divider hidden />
        {requestForum}

    )
  }
}

function mapStateToProps(state, ownProps) {
  return {account: state.account}
}

function mapDispatchToProps(dispatch) {
  return {actions: bindActionCreators(accountActions, dispatch)}
}

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);
<commit_msg>Removed groups from the sidebar<commit_after>import React from 'react'
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'
import { Divider, Header, Menu, Segment } from 'semantic-ui-react'
import * as accountActions from '../actions/accountActions'
import { Link } from 'react-router-dom'
import Login from '../components/elements/login'

class Sidebar extends React.Component {
  componentDidMount() {
    if (!this.props.account) {
      this.props.actions.fetchAccount()
    }
  }
  render() {
    const forums = this.props.forums;
    let requestForum = (
          <Segment basic textAlign='center'>

              Have an idea for a forum?

              Make a post on the <Link to='/forum/chainbb'>chainBB forum</Link> with what you would like to see or any ideas you may have.

          </Segment>
        )
        ,
        categories = (
          <Menu vertical fluid color='blue' size='small'>
            <Link className={`item ${(!forums || !forums.group) ? 'active' : ''}`} to='/'>
              General Forums
            </Link>
            <Link className={`item ${(forums && forums.group === 'steem') ? 'active' : ''}`} to='/forums/steem'>
              Steem Forums
            </Link>
            <Link className={`item ${(forums && forums.group === 'crypto') ? 'active' : ''}`} to='/forums/crypto'>
              Crypto Forums
            </Link>
            {/*
            <Menu.Item disabled>My Feed</Menu.Item>
            <Menu.Item disabled>Communities</Menu.Item>
            <Menu.Item disabled>Trending</Menu.Item>
            <Menu.Item disabled>New Posts</Menu.Item>
            <Menu.Item disabled>Promoted</Menu.Item>
            <Menu.Item disabled>Tags</Menu.Item>
            */}
          </Menu>
        )

    return (

        <Login {... this.props}/>
        <Divider hidden />
        {requestForum}

    )
  }
}

function mapStateToProps(state, ownProps) {
  return {account: state.account}
}

function mapDispatchToProps(dispatch) {
  return {actions: bindActionCreators(accountActions, dispatch)}
}

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);
<|endoftext|>