<commit_before>const rimraf = require('rimraf');
const fs = require('fs');
const sinon = require('sinon');
const os = require('os');
const simpleModel = require('../../../test-expected/sequelize/db-analysis-output/customers.expected.json');
const belongsToModel = require('../../../test-expected/sequelize/db-analysis-output/addresses.expected.json');
const otherAssociationsModel = require('../../../test-expected/sequelize/db-analysis-output/users.expected.json');
const joinTableWithIdKey = require('../../../test-expected/sequelize/db-analysis-output/only-foreign-keys-and-id.expected.json');
const exportModel = require('../../../test-expected/sequelize/db-analysis-output/export.expected.json');
const defaultValuesModel = require('../../../test-expected/sequelize/db-analysis-output/default-values.expected.js');
const parenthesisColumnName = require('../../../test-expected/sequelize/db-analysis-output/parenthesis.expected.json');
const parenthesisColumnNameUnderscored = require('../../../test-expected/sequelize/db-analysis-output/parenthesis_underscored.expected.json');
const parenthesisColumnNameUnderscoredTrue = require('../../../test-expected/sequelize/db-analysis-output/parenthesis_underscored_true.expected.json');
const context = require('../../../context');
const initContext = require('../../../context/init');

initContext(context);

const Dumper = require('../../../services/dumper');

function getDumper() {
  return new Dumper(context.inject());
}

const CONFIG = {
  appName: 'test-output/sequelize',
  dbDialect: 'postgres',
  dbConnectionUrl: 'postgres://localhost:27017',
  ssl: false,
  dbSchema: 'public',
  appHostname: 'localhost',
  appPort: 1654,
  db: true,
};

function cleanOutput() {
  rimraf.sync('./test-output/sequelize');
}

describe('services > dumper > sequelize', () => {
  it('should generate a simple model file', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(simpleModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/customers.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/customers.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with belongsTo associations', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(belongsToModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/addresses.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/addresses.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnName, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field and correct underscored fields', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnNameUnderscored, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis-underscored.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis_underscored.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field and underscored true', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnNameUnderscoredTrue, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis-underscored-true.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis_underscored_true.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with hasMany, hasOne and belongsToMany', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(otherAssociationsModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/users.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/users.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should still generate a model file when reserved word is used', async () => {
    expect.assertions(2);
    const dumper = getDumper();
    await dumper.dump(exportModel, CONFIG);
    const generatedModelFile = fs.readFileSync('./test-output/sequelize/models/export.js', 'utf8');
    const generatedRouteFile = fs.readFileSync('./test-output/sequelize/routes/export.js', 'utf8');
    const expectedModelFile = fs.readFileSync('./test-expected/sequelize/dumper-output/export.expected.js', 'utf-8');
    const expectedRouteFile = fs.readFileSync('./test-expected/sequelize/dumper-output/export.expected.route.js', 'utf-8');

    expect(generatedModelFile).toStrictEqual(expectedModelFile);
    expect(generatedRouteFile).toStrictEqual(expectedRouteFile);
    cleanOutput();
  });

  it('should generate a model with default values', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(defaultValuesModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/default-values.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/default-values.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate the model index file', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(simpleModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/index.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/index.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  describe('when generating the env file on various OS', () => {
    it('should generate the env file on Linux', async () => {
      expect.assertions(1);

      // Pretend we are on Linux.
      const osStub = sinon.stub(os, 'platform');
      osStub.returns('linux');

      const dumper = getDumper();
      await dumper.dump(simpleModel, CONFIG);

      osStub.restore();

      const generatedFile = fs.readFileSync('./test-output/sequelize/.env', 'utf8');
      const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/env.linux.expected', 'utf-8');

      expect(generatedFile).toStrictEqual(expectedFile);
      cleanOutput();
    });

    it('should generate the env file on macOS', async () => {
      expect.assertions(1);

      // Pretend we are on macOS.
      const osStub = sinon.stub(os, 'platform');
      osStub.returns('darwin');

      const dumper = getDumper();
      await dumper.dump(simpleModel, CONFIG);

      osStub.restore();

      const generatedFile = fs.readFileSync('./test-output/sequelize/.env', 'utf8');
      const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/env.darwin.expected', 'utf-8');

      expect(generatedFile).toStrictEqual(expectedFile);
      cleanOutput();
    });
  });

  it('should generate an id column on join tables with id primary key', async () => {
    expect.assertions(1);
    const dumper = await getDumper();
    await dumper.dump(joinTableWithIdKey);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/only-foreign-keys-and-id.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/only-foreign-keys-and-id.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });
});
<commit_msg>test(dumper): fix failing test on dumper (#530)<commit_after>const rimraf = require('rimraf');
const fs = require('fs');
const sinon = require('sinon');
const os = require('os');
const simpleModel = require('../../../test-expected/sequelize/db-analysis-output/customers.expected.json');
const belongsToModel = require('../../../test-expected/sequelize/db-analysis-output/addresses.expected.json');
const otherAssociationsModel = require('../../../test-expected/sequelize/db-analysis-output/users.expected.json');
const joinTableWithIdKey = require('../../../test-expected/sequelize/db-analysis-output/only-foreign-keys-and-id.expected.json');
const exportModel = require('../../../test-expected/sequelize/db-analysis-output/export.expected.json');
const defaultValuesModel = require('../../../test-expected/sequelize/db-analysis-output/default-values.expected.js');
const parenthesisColumnName = require('../../../test-expected/sequelize/db-analysis-output/parenthesis.expected.json');
const parenthesisColumnNameUnderscored = require('../../../test-expected/sequelize/db-analysis-output/parenthesis_underscored.expected.json');
const parenthesisColumnNameUnderscoredTrue = require('../../../test-expected/sequelize/db-analysis-output/parenthesis_underscored_true.expected.json');
const context = require('../../../context');
const initContext = require('../../../context/init');

initContext(context);

const Dumper = require('../../../services/dumper');

function getDumper() {
  return new Dumper(context.inject());
}

const CONFIG = {
  appName: 'test-output/sequelize',
  dbDialect: 'postgres',
  dbConnectionUrl: 'postgres://localhost:27017',
  ssl: false,
  dbSchema: 'public',
  appHostname: 'localhost',
  appPort: 1654,
  db: true,
};

function cleanOutput() {
  rimraf.sync('./test-output/sequelize');
}

describe('services > dumper > sequelize', () => {
  it('should generate a simple model file', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(simpleModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/customers.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/customers.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with belongsTo associations', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(belongsToModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/addresses.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/addresses.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnName, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field and correct underscored fields', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnNameUnderscored, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis-underscored.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis_underscored.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with correct parenthesis field and underscored true', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(parenthesisColumnNameUnderscoredTrue, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/parenthesis-underscored-true.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/parenthesis_underscored_true.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate a model file with hasMany, hasOne and belongsToMany', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(otherAssociationsModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/users.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/users.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should still generate a model file when reserved word is used', async () => {
    expect.assertions(2);
    const dumper = getDumper();
    await dumper.dump(exportModel, CONFIG);
    const generatedModelFile = fs.readFileSync('./test-output/sequelize/models/export.js', 'utf8');
    const generatedRouteFile = fs.readFileSync('./test-output/sequelize/routes/export.js', 'utf8');
    const expectedModelFile = fs.readFileSync('./test-expected/sequelize/dumper-output/export.expected.js', 'utf-8');
    const expectedRouteFile = fs.readFileSync('./test-expected/sequelize/dumper-output/export.expected.route.js', 'utf-8');

    expect(generatedModelFile).toStrictEqual(expectedModelFile);
    expect(generatedRouteFile).toStrictEqual(expectedRouteFile);
    cleanOutput();
  });

  it('should generate a model with default values', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(defaultValuesModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/default-values.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/default-values.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  it('should generate the model index file', async () => {
    expect.assertions(1);
    const dumper = getDumper();
    await dumper.dump(simpleModel, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/index.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/index.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });

  describe('when generating the env file on various OS', () => {
    it('should generate the env file on Linux', async () => {
      expect.assertions(1);

      // Pretend we are on Linux.
      const osStub = sinon.stub(os, 'platform');
      osStub.returns('linux');

      const dumper = getDumper();
      await dumper.dump(simpleModel, CONFIG);

      osStub.restore();

      const generatedFile = fs.readFileSync('./test-output/sequelize/.env', 'utf8');
      const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/env.linux.expected', 'utf-8');

      expect(generatedFile).toStrictEqual(expectedFile);
      cleanOutput();
    });

    it('should generate the env file on macOS', async () => {
      expect.assertions(1);

      // Pretend we are on macOS.
      const osStub = sinon.stub(os, 'platform');
      osStub.returns('darwin');

      const dumper = getDumper();
      await dumper.dump(simpleModel, CONFIG);

      osStub.restore();

      const generatedFile = fs.readFileSync('./test-output/sequelize/.env', 'utf8');
      const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/env.darwin.expected', 'utf-8');

      expect(generatedFile).toStrictEqual(expectedFile);
      cleanOutput();
    });
  });

  it('should generate an id column on join tables with id primary key', async () => {
    expect.assertions(1);
    const dumper = await getDumper();
    await dumper.dump(joinTableWithIdKey, CONFIG);
    const generatedFile = fs.readFileSync('./test-output/sequelize/models/only-foreign-keys-and-id.js', 'utf8');
    const expectedFile = fs.readFileSync('./test-expected/sequelize/dumper-output/only-foreign-keys-and-id.expected.js', 'utf-8');

    expect(generatedFile).toStrictEqual(expectedFile);
    cleanOutput();
  });
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var webserver = require('gulp-webserver');

var buildFrontEndDir = './frontend/build';

var port = process.env.PORT || 8080;

var serveApp = function serveAppTask() {
  console.log('Starting front end.');

  gulp.src(buildFrontEndDir)
    .pipe(webserver({
      host:             0.0.0.0,
      livereload:       false,
      directoryListing: false,
      open:             false,
      port:             port
    }));
};

// Starts the production workflow
gulp.task('default', function () {
  serveApp();
});
<commit_msg>Fixed lack of quotes.<commit_after>var gulp = require('gulp');
var webserver = require('gulp-webserver');

var buildFrontEndDir = './frontend/build';

var port = process.env.PORT || 8080;

var serveApp = function serveAppTask() {
  console.log('Starting front end.');

  gulp.src(buildFrontEndDir)
    .pipe(webserver({
      host:             '0.0.0.0',
      livereload:       false,
      directoryListing: false,
      open:             false,
      port:             port
    }));
};

// Starts the production workflow
gulp.task('default', function () {
  serveApp();
});
<|endoftext|>


<commit_before>"use strict";

exports.event = function (instance, event, session, callback) {

    var Flow = this;

    var config = instance._flow[event];
    var count = config.d ? (config.d.length || 0) : 0;
    var called = 0;
    var event_stream = {d:[/*S*/[/*H*/[/*H(o)*/]]]};
    var errorHappend;
    var check = function (err) {

        if (errorHappend) {
            return;
        }

        if (err) {
            errorHappend = true;
            return callback(err);
        };

        if (count === ++called) {
            callback(null, event_stream);
        }
    }

    // data sequence
    if (count > 0) {
        for (var i = 0, l = config.d.length; i < l; ++i) {
            resolveHandler(Flow, instance, session, event_stream.d, config.d[i], check);
        }
    }

    // end event
    if (config.e) {
        event_stream.e = resolveEvent(config.e);
    }

    // error event
    if (config.r) {
        event_stream.r = resolveEvent(config.r);
    }
};

function resolveEvent (event) {

    // normalize event config
    event = typeof event === 'string' ? [event, {}] : event;
    event[1] = event[1] || {};

    return event;
}

function resolveHandler (Flow, instance, session, sections, handler, callback) {

    var path = handler;
    var args = {};

    if (handler.constructor === Array) {
        path = handler[0];
        args = handler[1] || {};
    }

    var type = path[0];
    path = path.substr(1);

    var section = sections[sections.length - 1];

    if (type === ':' || type === '.') {
        section[0].push(null);
        return getMethodRef(
            Flow,
            instance,
            session,
            {
                position: section[0].length - 1,
                target: section[0],
                path: path,
                args: args,
                once: (type === '.'),
            },
            callback
        );
    }

    if (type === '>' || type === '|') {

        var net = path[0];
        path = path.substr(1);

        section = [[], [type, path]];
        sections.push(section);

        if (net === '*') {
            return getMethodRef(
                Flow,
                instance,
                session,
                {
                    position: 1,
                    target: section[1][1],
                    path: path,
                    args: args
                },
                callback
            );
        }

        return callback();
    }

    callback(new Error('Flow.parse: Invalid handler type:', type));
}

function getMethodRef (Flow, instance, session, method, callback) {

    var instanceName = instance._name;
    var path = method.path;

    if (path.indexOf('/') > 0) {
        path = path.split('/');
        instanceName = path[0];
        path = path[1];
    }

    Flow.load(instanceName, session, function (err, instance) {

        if (err) {
            return callback(err);
        }

        // get handler function
        var fn = getPathValue(path, [instance, global]);
        if (typeof fn !== 'function') {
            return callback(new Error('Flow.getEvent: Method "' + path + '" on instance "' + instance._name + '" not found.'));
        }

        method.target[method.position] = [fn, method.args, instance, method.once];
        callback();
    });
}

/**
 * Get a value from a property "path" (dot.notation).
 * path('Object.key.key.value'[, {'key': {'key': {'value': 123}}}]);
 *
 * @private
 * @param {string} The path in "dot" notation.
 * @param {array} The data objects, which are used to search the path.
 */
function getPathValue (path, scopes, count) {

    if (!path) {
        return;
    }

    // get scope
    count = count || 0;
    var scope = scopes[count];

    // if no scope is found
    if (!scope) {
        return;
    }

    // prepare path
    var o = path;
    path = path.split('.');

    // find keys in paths or return
    for (var i = 0; i < path.length; ++i) {
        if ((scope = scope[path[i]]) === undefined) {
            return scopes[++count] ? getPathValue(o, scopes, count) : undefined;
        }
    }

    return scope;
};
<commit_msg>error and end event config is just a string<commit_after>"use strict";

exports.event = function (instance, event, session, callback) {

    var Flow = this;

    var config = instance._flow[event];
    var count = config.d ? (config.d.length || 0) : 0;
    var called = 0;
    var event_stream = {d:[/*S*/[/*H*/[/*H(o)*/]]]};
    var errorHappend;
    var check = function (err) {

        if (errorHappend) {
            return;
        }

        if (err) {
            errorHappend = true;
            return callback(err);
        };

        if (count === ++called) {
            callback(null, event_stream);
        }
    }

    // data sequence
    if (count > 0) {
        for (var i = 0, l = config.d.length; i < l; ++i) {
            resolveHandler(Flow, instance, session, event_stream.d, config.d[i], check);
        }
    }

    // end event
    if (config.e) {
        event_stream.e = config.e;
    }

    // error event
    if (config.r) {
        event_stream.r = config.r;
    }
};

function resolveHandler (Flow, instance, session, sections, handler, callback) {

    var path = handler;
    var args = {};

    if (handler.constructor === Array) {
        path = handler[0];
        args = handler[1] || {};
    }

    var type = path[0];
    path = path.substr(1);

    var section = sections[sections.length - 1];

    if (type === ':' || type === '.') {
        section[0].push(null);
        return getMethodRef(
            Flow,
            instance,
            session,
            {
                position: section[0].length - 1,
                target: section[0],
                path: path,
                args: args,
                once: (type === '.'),
            },
            callback
        );
    }

    if (type === '>' || type === '|') {

        var net = path[0];
        path = path.substr(1);

        section = [[], [type, path]];
        sections.push(section);

        if (net === '*') {
            return getMethodRef(
                Flow,
                instance,
                session,
                {
                    position: 1,
                    target: section[1][1],
                    path: path,
                    args: args
                },
                callback
            );
        }

        return callback();
    }

    callback(new Error('Flow.parse: Invalid handler type:', type));
}

function getMethodRef (Flow, instance, session, method, callback) {

    var instanceName = instance._name;
    var path = method.path;

    if (path.indexOf('/') > 0) {
        path = path.split('/');
        instanceName = path[0];
        path = path[1];
    }

    Flow.load(instanceName, session, function (err, instance) {

        if (err) {
            return callback(err);
        }

        // get handler function
        var fn = getPathValue(path, [instance, global]);
        if (typeof fn !== 'function') {
            return callback(new Error('Flow.getEvent: Method "' + path + '" on instance "' + instance._name + '" not found.'));
        }

        method.target[method.position] = [fn, method.args, instance, method.once];
        callback();
    });
}

/**
 * Get a value from a property "path" (dot.notation).
 * path('Object.key.key.value'[, {'key': {'key': {'value': 123}}}]);
 *
 * @private
 * @param {string} The path in "dot" notation.
 * @param {array} The data objects, which are used to search the path.
 */
function getPathValue (path, scopes, count) {

    if (!path) {
        return;
    }

    // get scope
    count = count || 0;
    var scope = scopes[count];

    // if no scope is found
    if (!scope) {
        return;
    }

    // prepare path
    var o = path;
    path = path.split('.');

    // find keys in paths or return
    for (var i = 0; i < path.length; ++i) {
        if ((scope = scope[path[i]]) === undefined) {
            return scopes[++count] ? getPathValue(o, scopes, count) : undefined;
        }
    }

    return scope;
};
<|endoftext|>


<commit_before>describe("ClientController", function() {
    var resourceCallback;
    beforeEach(function() {
        this.scope = jasmine.createSpyObj("$scope", ['$clients']);

        this.resourceFactory = {clientResource: {
            getAllClients: jasmine.createSpy('clientResource.getAllClients()').andCallFake(function(callback) {
                resourceCallback = callback;
            })
        }};

        this.paginatorService = jasmine.createSpyObj("paginatorService", ["paginate"]);

        this.paginatorService.when("paginate").thenReturn( function() {
            resourceFactory.clientResource.getAllClients();
        })

        this.controller = new mifosX.controllers.ClientController(this.scope, this.resourceFactory, this.paginatorService);
    });

    it("should call the clientResource with the correct method", function() {
        expect(this.resourceFactory.clientResource.getAllClients).toHaveBeenCalled();
    });
});<commit_msg>tried things<commit_after>describe("ClientController", function() {
    var resourceCallback;
    beforeEach(function() {
        this.scope = jasmine.createSpyObj("$scope", ['$clients']);

        this.resourceFactory = {clientResource: {
            getAllClients: jasmine.createSpy('clientResource.getAllClients()').andCallFake(function(callback) {
                resourceCallback = callback;
            })
        }};

        this.paginatorService = jasmine.createSpyObj("paginatorService", ["paginate"]);

//        spyOn(this.paginatorService, 'paginate').andCallThrough();

        this.controller = new mifosX.controllers.ClientController(this.scope, this.resourceFactory, this.paginatorService);
    });

    it("should call the clientResource with the correct method", function() {
        expect(this.resourceFactory.clientResource.getAllClients).toHaveBeenCalled();
    });
});<|endoftext|>


<commit_before>/**
 * gulpfile.js
 * For build instructions, please see README.md.
 *
 * Copyright (C) 2014-2016 Karim Alibhai.
 **/

'use strict';

var gulp = require('gulp'),
    jslint = require('./');

// lint all code
gulp.task('default', function () {
    return gulp.src(['gulpfile.js', 'test/test-gulp.jslint.js'])

        // pass your directives
        // as an object
        .pipe(jslint({
            // these directives can
            // be found in the official
            // JSLint documentation.
            node: true,
            nomen: true,

            // you can also set global
            // declarations for all source
            // files like so:
            global: [],
            predef: []

            // both ways will achieve the
            // same result; predef will be
            // given priority because it is
            // promoted by JSLint
        }))

        // pass in your prefered reporter like so:
        .pipe(jslint.reporter('default', true));
});
<commit_msg>Remove nomen from gulpfile<commit_after>/**
 * gulpfile.js
 * For build instructions, please see README.md.
 *
 * Copyright (C) 2014-2016 Karim Alibhai.
 **/

'use strict';

var gulp = require('gulp'),
    jslint = require('./');

// lint all code
gulp.task('default', function () {
    return gulp.src(['gulpfile.js', 'test/test-gulp.jslint.js'])

        // pass your directives
        // as an object
        .pipe(jslint({
            // these directives can
            // be found in the official
            // JSLint documentation.
            node: true,

            // you can also set global
            // declarations for all source
            // files like so:
            global: [],
            predef: []

            // both ways will achieve the
            // same result; predef will be
            // given priority because it is
            // promoted by JSLint
        }))

        // pass in your prefered reporter like so:
        .pipe(jslint.reporter('default', true));
});
<|endoftext|>


<commit_before>const _ = require('lodash');
const Promise = require('bluebird');
const debug = require('debug')('lib:parse');
const moment = require('moment');
const nconf = require('nconf');
const xpath = require('xpath');
const xmldom = require('xmldom');
const JSDOM = require('jsdom').JSDOM;

const mongo = require('./mongo');
const sequence = require('../parsers/components/utils/sequence');
const summarize = require('../parsers/components/utils/summarize');
const parserDebug = require('../parsers/components/utils/parserDebug');
const echoes = require('./echoes');
const utils = require('./utils');
const aggregated = require('./aggregated');
const glue = require('./glue');

function checkMetadata(impression, repeat) {
    if(_.isUndefined(impression.id))
        throw new Error("impression missing");

    return mongo
        .readOne(nconf.get('schema').metadata, { id: impression.id })
        .then(function(i) {
            if( _.get(i, 'id') === impression.id && !repeat) {
                debug("metadata [%s] already exists: skipping", i.id);
                return null;
            }

            if( _.get(i, 'id') === impression.id && repeat) {
                debug("metadata [%s] exists, but repeat is requested", i.id);
                return Promise.all([
                    mongo.remove(nconf.get('schema').metadata, { id: impression.id }),
                    mongo.remove(nconf.get('schema').summary, { id: impression.id })
                ])
                .return(impression);
            }

            /* else if _.isUndefined(i) is returned the impression */
            return impression;
        });
}

function initialize(impression) {
    const xmlerr = { warning: 0, error: 0, fatal: 0 };
    var domOptions = {
          errorHandler:{
              warning: function() { xmlerr.warning += 1; },
              error: function() { xmlerr.error += 1; },
              fatalError: function() { xmlerr.fatal += 1;  },
          }
    };
    /* this is the envelope with get appended the metadata from the various parsers */
    return {
        impression,
        xmlerr,
        xpath,
        jsdom: new JSDOM(impression.html).window.document,
        dom: new xmldom.DOMParser(domOptions).parseFromString(impression.html),
    };
}

function finalize(envelopes) {
    if(!_.size(envelopes))
        return { metadata: [], summary: [], statistics: [], parsers: [], errors: [] };

    /* here is build the new complex object which travels in the pipeline,
     * metadata & parsers are the internal content, not meant to be public */

    const errors = _.reduce(envelopes, function(memo, e) {
        if(!_.size(e.errors))
            return memo;
        var r = {
            errors: e.errors,
            when:  new Date(),
            id: e.impression.id,
            timelineId: e.impression.timelineId
        }
        memo.push(r);
        return memo;
    }, []);

    const removef = ['dom', 'jsdom', 'xpath', 'xmlerr', 'impression', 'errors'];
    const impressionFields =
        ['id', 'timelineId', 'userId', 'impressionOrder', 'impressionTime'];

    const metadata = _.map(envelopes, function(e) {
        return _.extend(
            _.pick(e.impression, impressionFields),
            _.omit(e, removef),
            { when: new Date() }
        );
    });
    const parsers = _.map(metadata, parserDebug);

    /* summary is the format used for user-facing API */
    const summary = _.map(metadata, summarize);
    /* statistics are the public information on how fbtrex is doing */
    const statistics = _.map(summary, aggregated.computeStats);

    return {
        metadata,
        parsers,
        summary,
        statistics,
        errors
    };
}

function logSummary(blobs) {
    _.each(blobs.summary, function(e) {
        echoes.echo(
            _.extend({'index': 'parserv' },
            _.pick(e, ['errors', 'type', 'publicationTime', 'postId',
                       'permaLink', 'author', 'textlength', 'impressionTime',
                       'impressionOrder', 'pseudo', 'timeline', 'regexp' ])
            )
        );
    });

    /* the `fulldump` is set by executers or by `parsers/precise.js` */
    if(nconf.get('fulldump'))
        _.times(_.size(blobs.metadata), function(o, i) {
            let s = _.nth(blobs.summary, i);
            console.log(JSON.stringify(s, undefined, 1));
            console.log("\x1b[36m");
            let m = _.nth(blobs.metadata, i);
            console.log(JSON.stringify(m, undefined, 1));
        });

    /* this is dumped even without fulldump */
    const E = "\x1b[47m\x1b[31m";
    _.each(blobs.errors, function(o) {
        console.log(E, JSON.stringify(o, undefined, 2));
    });
}

function mark(blobs) {
    return Promise.map(blobs.metadata, function(e) {
        return mongo
            .readOne(nconf.get('schema').htmls, { id: e.id })
            .then(function(existing) {
                existing.processed = true;
                return mongo
                    .updateOne(nconf.get('schema').htmls, { _id: existing._id }, existing);
            });
    }, { concurrency: 1});
}

function save(blobs) {
    let chain = [];
    debug("Received %d metadata and %d errors", _.size(blobs.metadata), _.size(blobs.errors));

    if(_.size(blobs.metadata))
        chain.push(
            mongo.writeMany(nconf.get('schema').metadata, blobs.metadata)  );

    if(_.size(blobs.metadata) && !nconf.get('onlymetadata') ) {
        chain.push(
            mongo.writeMany(nconf.get('schema').summary, blobs.summary)  );
        chain.push(
            aggregated.updateHourly(blobs.statistics)   );
        /*
         - still unclear how and what we should records
        chain.push(
            mongo.writeMany(nconf.get('schema').parsers, blobs.parsers)   );
         */
    }

    if(_.size(blobs.errors) && !nconf.get('onlymetadata') )
        chain.push(
            mongo.writeMany(nconf.get('schema').errors, blobs.errors)  );

    return Promise
        .all(chain)
        .return({
            metadata: _.size(blobs.metadata),
            errors: _.size(blobs.errors)
        })
        .catch(function(error) {
            console.log("error in saving:", error.message);
            return null;
        });
}

function postIdCount(e) {
    /* this function creates certain conditional fields in metadata:
     * - postId is build at the end of `sequence`
     * - postCount { personal, global } gets created always */

    // this is slowing too much the parsing, I'm going to removed it
    // --- sadClaudio

    if(!e.postId)
        return e;

    e.postCount = { personal: null, global: null };

    return Promise.all([
        mongo.count(nconf.get('schema').metadata,
            { linkedtime: { postId: e.postId } }),
        mongo.count(nconf.get('schema').metadata,
            { linkedtime: { postId: e.postId }, userId: e.userId })
    ])
    .then(function(results) {
        e.postCount.global = results[0];
        e.postCount.personal = results[1];
        return e;
    });
};

function semanticIdCount(e) {
    /* this function creates certain conditional fields in metadata:
     * * if there is no .texts or zero-length texts, it returns
     * - semanticId gets created always
     * - semanticCount { personal, global } gets created always
     * - semantic: true, gets created when the semanticCount.global is zero  */

    if(!e.fullTextSize)
        return e;

    e.semanticId = utils.hash({ text: e.fullText });
    e.semanticCount = { personal: null, global: null };

    return Promise.all([
        mongo.count(nconf.get('schema').metadata, { semanticId: e.semanticId }),
        mongo.count(nconf.get('schema').metadata, { semanticId: e.semanticId, userId: e.userId })
    ])
    .then(function(results) {
        e.semanticCount.global = results[0];
        e.semanticCount.personal = results[1];

        /* only the first metadata with a due semanticId is marked with `semantic`,
         * this will be processed later by lib/semantic.js */
        if(!e.semanticCount.global)
            e.semantic = true;
        return e;
    });
};

function mergeHTMLImpression(html) {
    return mongo
        .readOne(nconf.get('schema').impressions, { id: html.impressionId })
        .then(function(impression) {
            _.unset(impression, 'id');
            _.unset(impression, 'htmlId');
            return _.merge(html, impression);
        });
}

function parseHTML(htmlfilter, repeat) {
    return mongo
        .read(nconf.get('schema').htmls, htmlfilter)
        .then(function(found) {
            if(_.size(found) > 0)
                return found;
            if(nconf.get('retrive') != true)
                return [];
            return glue.retrive(htmlfilter)
                .then(glue.writers)
                .tap(function(x) {
                    if(x && x[2] && htmlfilter.id == x[2][0].id)
                        debug("Successfully retrived remote content");
                    else
                        debug("Failure in retriving remote content!");
                })
                .then(function() {
                    return mongo
                        .read(nconf.get('schema').htmls, htmlfilter);
                });
        })
        .catch(function(error) {
            debug("Managed error in retrieving content: %s", error);
            // console.error(error.stack);
            return [];
        })
        .map(mergeHTMLImpression, { concurrency: 1 })
        .then(_.compact)
        .then(function(impressions) {
            return _.orderBy(impressions, { impressionOrder: -1 });
        })
        .tap(function(impressions) {
            if(_.size(impressions)) {
                const firstT = moment(_.first(impressions).impressionTime).format("DD/MMM/YY HH:mm");
                const lastT = moment(_.last(impressions).impressionTime).format("DD/MMM/YY HH:mm");
                const humanized = moment
                    .duration( _.last(impressions).impressionTime - _.first(impressions).impressionTime )
                    .humanize();
                debug("Processing %d impressionsOrder %s [%s] %s %s [%s] %s",
                    /*                                    ^^^^^^^^^^^^^ conditionals */
                    _.size(impressions),
                    _.first(impressions).impressionOrder, firstT,
                    _.size(impressions) > 1 ? "-" : "",
                    _.size(impressions) > 1 ? _.last(impressions).impressionOrder : "",
                    _.size(impressions) > 1 ? "[" + lastT + "]" : "",
                    _.size(impressions) > 1 ? "(" + humanized + ")" : ""
                );
            }
        })
        .map(function(e) {
            return checkMetadata(e, repeat);
        }, { concurrency: 1 })
        .then(_.compact)
        .map(initialize)
        .map(sequence, { concurrency: 1 })
        /* this is the function processing the parsers
         * it is call of every .id which should be analyzed */
        .catch(function(error) {
            debug("[E] Unmanaged error in parser sequence: %s", error.message);
            console.log(error.stack);
            return null;
        })
        .then(function(metadata) {
            if(!metadata)
                return [];

            debug("⁂  completed %d metadata", _.size(metadata));
            if(!_.isUndefined(nconf.get('verbose')))
                debug("⁂  %s", JSON.stringify(metadata, undefined, 2));

            return metadata;
        })
        // .map(postIdCount)
        .map(semanticIdCount)
        .then(finalize)
        .tap(logSummary)
        .tap(mark)
        .then(save)
        .catch(function(error) {
            console.log("[error after parsing]", error.message);
            console.log(error.stack);
            return null;
        });
}

module.exports = {
    checkMetadata: checkMetadata,
    initialize: initialize,
    mergeHTMLImpression: mergeHTMLImpression,
    finalize: finalize,
    logSummary: logSummary,
    save: save,
    postIdCount: postIdCount,
    semanticIdCount: semanticIdCount,
    mark: mark,
    parseHTML: parseHTML,
};
<commit_msg>removed also semanticIdCount for performance reasons and because was not really used<commit_after>const _ = require('lodash');
const Promise = require('bluebird');
const debug = require('debug')('lib:parse');
const moment = require('moment');
const nconf = require('nconf');
const xpath = require('xpath');
const xmldom = require('xmldom');
const JSDOM = require('jsdom').JSDOM;

const mongo = require('./mongo');
const sequence = require('../parsers/components/utils/sequence');
const summarize = require('../parsers/components/utils/summarize');
const parserDebug = require('../parsers/components/utils/parserDebug');
const echoes = require('./echoes');
const utils = require('./utils');
const aggregated = require('./aggregated');
const glue = require('./glue');

function checkMetadata(impression, repeat) {
    if(_.isUndefined(impression.id))
        throw new Error("impression missing");

    return mongo
        .readOne(nconf.get('schema').metadata, { id: impression.id })
        .then(function(i) {
            if( _.get(i, 'id') === impression.id && !repeat) {
                debug("metadata [%s] already exists: skipping", i.id);
                return null;
            }

            if( _.get(i, 'id') === impression.id && repeat) {
                debug("metadata [%s] exists, but repeat is requested", i.id);
                return Promise.all([
                    mongo.remove(nconf.get('schema').metadata, { id: impression.id }),
                    mongo.remove(nconf.get('schema').summary, { id: impression.id })
                ])
                .return(impression);
            }

            /* else if _.isUndefined(i) is returned the impression */
            return impression;
        });
}

function initialize(impression) {
    const xmlerr = { warning: 0, error: 0, fatal: 0 };
    var domOptions = {
          errorHandler:{
              warning: function() { xmlerr.warning += 1; },
              error: function() { xmlerr.error += 1; },
              fatalError: function() { xmlerr.fatal += 1;  },
          }
    };
    /* this is the envelope with get appended the metadata from the various parsers */
    return {
        impression,
        xmlerr,
        xpath,
        jsdom: new JSDOM(impression.html).window.document,
        dom: new xmldom.DOMParser(domOptions).parseFromString(impression.html),
    };
}

function finalize(envelopes) {
    if(!_.size(envelopes))
        return { metadata: [], summary: [], statistics: [], parsers: [], errors: [] };

    /* here is build the new complex object which travels in the pipeline,
     * metadata & parsers are the internal content, not meant to be public */

    const errors = _.reduce(envelopes, function(memo, e) {
        if(!_.size(e.errors))
            return memo;
        var r = {
            errors: e.errors,
            when:  new Date(),
            id: e.impression.id,
            timelineId: e.impression.timelineId
        }
        memo.push(r);
        return memo;
    }, []);

    const removef = ['dom', 'jsdom', 'xpath', 'xmlerr', 'impression', 'errors'];
    const impressionFields =
        ['id', 'timelineId', 'userId', 'impressionOrder', 'impressionTime'];

    const metadata = _.map(envelopes, function(e) {
        return _.extend(
            _.pick(e.impression, impressionFields),
            _.omit(e, removef),
            { when: new Date() }
        );
    });
    const parsers = _.map(metadata, parserDebug);

    /* summary is the format used for user-facing API */
    const summary = _.map(metadata, summarize);
    /* statistics are the public information on how fbtrex is doing */
    const statistics = _.map(summary, aggregated.computeStats);

    return {
        metadata,
        parsers,
        summary,
        statistics,
        errors
    };
}

function logSummary(blobs) {
    _.each(blobs.summary, function(e) {
        echoes.echo(
            _.extend({'index': 'parserv' },
            _.pick(e, ['errors', 'type', 'publicationTime', 'postId',
                       'permaLink', 'author', 'textlength', 'impressionTime',
                       'impressionOrder', 'pseudo', 'timeline', 'regexp' ])
            )
        );
    });

    /* the `fulldump` is set by executers or by `parsers/precise.js` */
    if(nconf.get('fulldump'))
        _.times(_.size(blobs.metadata), function(o, i) {
            let s = _.nth(blobs.summary, i);
            console.log(JSON.stringify(s, undefined, 1));
            console.log("\x1b[36m");
            let m = _.nth(blobs.metadata, i);
            console.log(JSON.stringify(m, undefined, 1));
        });

    /* this is dumped even without fulldump */
    const E = "\x1b[47m\x1b[31m";
    _.each(blobs.errors, function(o) {
        console.log(E, JSON.stringify(o, undefined, 2));
    });
}

function mark(blobs) {
    return Promise.map(blobs.metadata, function(e) {
        return mongo
            .readOne(nconf.get('schema').htmls, { id: e.id })
            .then(function(existing) {
                existing.processed = true;
                return mongo
                    .updateOne(nconf.get('schema').htmls, { _id: existing._id }, existing);
            });
    }, { concurrency: 1});
}

function save(blobs) {
    let chain = [];
    debug("Received %d metadata and %d errors", _.size(blobs.metadata), _.size(blobs.errors));

    if(_.size(blobs.metadata))
        chain.push(
            mongo.writeMany(nconf.get('schema').metadata, blobs.metadata)  );

    if(_.size(blobs.metadata) && !nconf.get('onlymetadata') ) {
        chain.push(
            mongo.writeMany(nconf.get('schema').summary, blobs.summary)  );
        chain.push(
            aggregated.updateHourly(blobs.statistics)   );
        /*
         - still unclear how and what we should records
        chain.push(
            mongo.writeMany(nconf.get('schema').parsers, blobs.parsers)   );
         */
    }

    if(_.size(blobs.errors) && !nconf.get('onlymetadata') )
        chain.push(
            mongo.writeMany(nconf.get('schema').errors, blobs.errors)  );

    return Promise
        .all(chain)
        .return({
            metadata: _.size(blobs.metadata),
            errors: _.size(blobs.errors)
        })
        .catch(function(error) {
            console.log("error in saving:", error.message);
            return null;
        });
}

function postIdCount(e) {
    /* this function creates certain conditional fields in metadata:
     * - postId is build at the end of `sequence`
     * - postCount { personal, global } gets created always */

    // this is slowing too much the parsing, I'm going to removed it
    // --- sadClaudio

    if(!e.postId)
        return e;

    e.postCount = { personal: null, global: null };

    return Promise.all([
        mongo.count(nconf.get('schema').metadata,
            { linkedtime: { postId: e.postId } }),
        mongo.count(nconf.get('schema').metadata,
            { linkedtime: { postId: e.postId }, userId: e.userId })
    ])
    .then(function(results) {
        e.postCount.global = results[0];
        e.postCount.personal = results[1];
        return e;
    });
};

function semanticIdCount(e) {
    /* this function creates certain conditional fields in metadata:
     * * if there is no .texts or zero-length texts, it returns
     * - semanticId gets created always
     * - semanticCount { personal, global } gets created always
     * - semantic: true, gets created when the semanticCount.global is zero  */

    if(!e.fullTextSize)
        return e;

    e.semanticId = utils.hash({ text: e.fullText });
    e.semanticCount = { personal: null, global: null };

    return Promise.all([
        mongo.count(nconf.get('schema').metadata, { semanticId: e.semanticId }),
        mongo.count(nconf.get('schema').metadata, { semanticId: e.semanticId, userId: e.userId })
    ])
    .then(function(results) {
        e.semanticCount.global = results[0];
        e.semanticCount.personal = results[1];

        /* only the first metadata with a due semanticId is marked with `semantic`,
         * this will be processed later by lib/semantic.js */
        if(!e.semanticCount.global)
            e.semantic = true;
        return e;
    });
};

function mergeHTMLImpression(html) {
    return mongo
        .readOne(nconf.get('schema').impressions, { id: html.impressionId })
        .then(function(impression) {
            _.unset(impression, 'id');
            _.unset(impression, 'htmlId');
            return _.merge(html, impression);
        });
}

function parseHTML(htmlfilter, repeat) {
    return mongo
        .read(nconf.get('schema').htmls, htmlfilter)
        .then(function(found) {
            if(_.size(found) > 0)
                return found;
            if(nconf.get('retrive') != true)
                return [];
            return glue.retrive(htmlfilter)
                .then(glue.writers)
                .tap(function(x) {
                    if(x && x[2] && htmlfilter.id == x[2][0].id)
                        debug("Successfully retrived remote content");
                    else
                        debug("Failure in retriving remote content!");
                })
                .then(function() {
                    return mongo
                        .read(nconf.get('schema').htmls, htmlfilter);
                });
        })
        .catch(function(error) {
            debug("Managed error in retrieving content: %s", error);
            // console.error(error.stack);
            return [];
        })
        .map(mergeHTMLImpression, { concurrency: 1 })
        .then(_.compact)
        .then(function(impressions) {
            return _.orderBy(impressions, { impressionOrder: -1 });
        })
        .tap(function(impressions) {
            if(_.size(impressions)) {
                const firstT = moment(_.first(impressions).impressionTime).format("DD/MMM/YY HH:mm");
                const lastT = moment(_.last(impressions).impressionTime).format("DD/MMM/YY HH:mm");
                const humanized = moment
                    .duration( _.last(impressions).impressionTime - _.first(impressions).impressionTime )
                    .humanize();
                debug("Processing %d impressionsOrder %s [%s] %s %s [%s] %s",
                    /*                                    ^^^^^^^^^^^^^ conditionals */
                    _.size(impressions),
                    _.first(impressions).impressionOrder, firstT,
                    _.size(impressions) > 1 ? "-" : "",
                    _.size(impressions) > 1 ? _.last(impressions).impressionOrder : "",
                    _.size(impressions) > 1 ? "[" + lastT + "]" : "",
                    _.size(impressions) > 1 ? "(" + humanized + ")" : ""
                );
            }
        })
        .map(function(e) {
            return checkMetadata(e, repeat);
        }, { concurrency: 1 })
        .then(_.compact)
        .map(initialize)
        .map(sequence, { concurrency: 1 })
        /* this is the function processing the parsers
         * it is call of every .id which should be analyzed */
        .catch(function(error) {
            debug("[E] Unmanaged error in parser sequence: %s", error.message);
            console.log(error.stack);
            return null;
        })
        .then(function(metadata) {
            if(!metadata)
                return [];

            debug("⁂  completed %d metadata", _.size(metadata));
            if(!_.isUndefined(nconf.get('verbose')))
                debug("⁂  %s", JSON.stringify(metadata, undefined, 2));

            return metadata;
        })
        //.map(postIdCount)
        //.map(semanticIdCount)
        .then(finalize)
        .tap(logSummary)
        .tap(mark)
        .then(save)
        .catch(function(error) {
            console.log("[error after parsing]", error.message);
            console.log(error.stack);
            return null;
        });
}

module.exports = {
    checkMetadata: checkMetadata,
    initialize: initialize,
    mergeHTMLImpression: mergeHTMLImpression,
    finalize: finalize,
    logSummary: logSummary,
    save: save,
    postIdCount: postIdCount,
    semanticIdCount: semanticIdCount,
    mark: mark,
    parseHTML: parseHTML,
};
<|endoftext|>


<commit_before>import React from 'react';
import Route from 'react-router-dom/Route';
import { connectFor } from '@folio/stripes-connect';
import ErrorBoundary from '@folio/stripes-components/lib/ErrorBoundary';
import { modules } from 'stripes-config'; // eslint-disable-line
import { StripesContext } from './StripesContext';
import AddContext from './AddContext';
import TitleManager from './components/TitleManager';

if (!Array.isArray(modules.app) && modules.length < 0) {
  throw new Error('At least one module of type "app" must be enabled.');
}

function getModuleRoutes(stripes) {
  const { intl } = stripes;

  return modules.app.map((module) => {
    const name = module.module.replace(/^@folio\//, '');
    const perm = `module.${name}.enabled`;
    if (!stripes.hasPerm(perm)) return null;

    const connect = connectFor(module.module, stripes.epics, stripes.logger);
    const Current = connect(module.getModule());
    const moduleStripes = stripes.clone({ connect });

    module.displayName = intl.formatMessage({
      id: module.displayName,
      defaultMessage: module.displayName,
    });

    return (
      <Route
        path={module.route}
        key={module.route}
        render={props => (
          <StripesContext.Provider value={moduleStripes}>
            <AddContext context={{ stripes: moduleStripes }}>
              <div id={`${name}-module-display`} data-module={module.module} data-version={module.version} >
                <ErrorBoundary>
                  <TitleManager page={module.displayName}>
                    <Current {...props} connect={connect} stripes={moduleStripes} />
                  </TitleManager>
                </ErrorBoundary>

            </AddContext>
          </StripesContext.Provider>
        )}
      />
    );
  }).filter(x => x);
}

export default getModuleRoutes;
<commit_msg>Use translated module names in doc.title<commit_after>import React from 'react';
import Route from 'react-router-dom/Route';
import { connectFor } from '@folio/stripes-connect';
import ErrorBoundary from '@folio/stripes-components/lib/ErrorBoundary';
import { modules } from 'stripes-config'; // eslint-disable-line
import { StripesContext } from './StripesContext';
import AddContext from './AddContext';
import TitleManager from './components/TitleManager';

if (!Array.isArray(modules.app) && modules.length < 0) {
  throw new Error('At least one module of type "app" must be enabled.');
}

function getModuleRoutes(stripes) {
  const { intl } = stripes;

  return modules.app.map((module) => {
    const name = module.module.replace(/^@folio\//, '');
    const perm = `module.${name}.enabled`;
    if (!stripes.hasPerm(perm)) return null;

    const connect = connectFor(module.module, stripes.epics, stripes.logger);
    const Current = connect(module.getModule());
    const moduleStripes = stripes.clone({ connect });

    const displayName = intl.formatMessage({
      id: module.displayName,
      defaultMessage: module.displayName,
    });

    return (
      <Route
        path={module.route}
        key={module.route}
        render={props => (
          <StripesContext.Provider value={moduleStripes}>
            <AddContext context={{ stripes: moduleStripes }}>
              <div id={`${name}-module-display`} data-module={module.module} data-version={module.version} >
                <ErrorBoundary>
                  <TitleManager page={displayName}>
                    <Current {...props} connect={connect} stripes={moduleStripes} />
                  </TitleManager>
                </ErrorBoundary>

            </AddContext>
          </StripesContext.Provider>
        )}
      />
    );
  }).filter(x => x);
}

export default getModuleRoutes;
<|endoftext|>


<commit_before>// VVVV.js -- Visual Web Client Programming
// (c) 2011 Matthias Zauner
// VVVV.js is freely distributable under the MIT license.
// Additional authors of sub components are mentioned at the specific code locations.

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Polar (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Polar3d = function(id, graph) {
  this.constructor(id, "Polar (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xIn = this.addInputPin('X', [0], this);
  var yIn = this.addInputPin('Y', [0], this);
  var zIn = this.addInputPin('Z', [-1], this);

  // output pins
  var pitchOut = this.addOutputPin('Pitch', [0], this);
  var yawOut = this.addOutputPin('Yaw', [0], this);
  var lengthOut = this.addOutputPin('Length', [1], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var x = xIn.getValue(i);
      var y = yIn.getValue(i);
      var z = zIn.getValue(i);

      var len = Math.sqrt(x*x + y*y + z*z );

      yawOut.setValue(i, Math.atan2(-x, -z) / (2*Math.PI));
      pitchOut.setValue(i, len == 0 ? 0 : Math.acos(-y/len) / (2*Math.PI) - 0.25);
      lengthOut.setValue(i, len);
    }

    yawOut.setSliceCount(maxSize);
    pitchOut.setSliceCount(maxSize);
    lengthOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Polar3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Cartesian (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Cartesian3d = function(id, graph) {
  this.constructor(id, "Cartesian (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var pitchIn = this.addInputPin('Pitch', [0], this);
  var yawIn = this.addInputPin('Yaw', [0], this);
  var lengthIn = this.addInputPin('Length', [1], this);

  // output pins
  var xOut = this.addOutputPin('X', [0], this);
  var yOut = this.addOutputPin('Y', [0], this);
  var zOut = this.addOutputPin('Z', [1], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var pitch = (pitchIn.getValue(i) + 0.25) * 2 * Math.PI;
      var yaw = yawIn.getValue(i) * 2 * Math.PI;
      var length = lengthIn.getValue(i);

      zOut.setValue(i, -length * Math.cos(yaw) * Math.sin(pitch));
      xOut.setValue(i, -length * Math.sin(yaw) * Math.sin(pitch));
      yOut.setValue(i, -length * Math.cos(pitch));
    }

    xOut.setSliceCount(maxSize);
    yOut.setSliceCount(maxSize);
    zOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Cartesian3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Normalize (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Normalize3d = function(id, graph) {
  this.constructor(id, "Normalize (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xIn = this.addInputPin('X', [1], this);
  var yIn = this.addInputPin('Y', [0], this);
  var zIn = this.addInputPin('Z', [0], this);

  // output pins
  var normalizedxOut = this.addOutputPin('NormalizedX', [1], this);
  var normalizedyOut = this.addOutputPin('NormalizedY', [0], this);
  var normalizedzOut = this.addOutputPin('NormalizedZ', [0], this);
  var inputlengthOut = this.addOutputPin('Input Length', [0], this);

  this.evaluate = function() {

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var x = xIn.getValue(i);
      var y = yIn.getValue(i);
      var z = zIn.getValue(i);

      var len = Math.sqrt(x*x + y*y + z*z);

      normalizedxOut.setValue(i, len == 0 ? 0.0 : x / len);
      normalizedyOut.setValue(i, len == 0 ? 0.0 : y / len);
      normalizedzOut.setValue(i, len == 0 ? 0.0 : z / len);
      inputlengthOut.setValue(i, len);
    }

    normalizedxOut.setSliceCount(maxSize);
    normalizedyOut.setSliceCount(maxSize);
    normalizedzOut.setSliceCount(maxSize);
    inputlengthOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Normalize3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Normalize (3d Vector)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Normalize3dVector = function(id, graph) {
  this.constructor(id, "Normalize (3d Vector)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xyzIn = this.addInputPin('XYZ', [], this);

  // output pins
  var normalizedxyzOut = this.addOutputPin('NormalizedXYZ', [], this);
  var inputlengthOut = this.addOutputPin('Input Length', [0], this);

  this.evaluate = function() {

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var xyz = xyzIn.getValue(i, 3);

      var len = Math.sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1] + xyz[2]*xyz[2]);

      normalizedxyzOut.setValue(i*3, len == 0 ? 0.0 : xyz[0]/len);
      normalizedxyzOut.setValue(i*3 + 1, len == 0 ? 0.0 : xyz[1]/len);
      normalizedxyzOut.setValue(i*3 + 2, len == 0 ? 0.0 : xyz[2]/len);
      inputlengthOut.setValue(i, len);
    }

    normalizedxyzOut.setSliceCount(Math.ceil(maxSize/3) * 3);
    inputlengthOut.setSliceCount(Math.ceil(maxSize/3));
  }

}
VVVV.Nodes.Normalize3dVector.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Multiply (3d Cross)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Multiply3dCross = function(id, graph) {
  this.constructor(id, "Multiply (3d Cross)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var input1xyzIn = this.addInputPin('Input1 XYZ', [], this);
  var input2xyzIn = this.addInputPin('Input2 XYZ', [], this);

  // output pins
  var outputxyzOut = this.addOutputPin('Output XYZ', [], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var input1xyz = input1xyzIn.getValue(i, 3);
      var input2xyz = input2xyzIn.getValue(i, 3);

      outputxyzOut.setValue(i*3 + 0, input1xyz[1]*input2xyz[2] - input1xyz[2]*input2xyz[1]);
      outputxyzOut.setValue(i*3 + 1, -(input1xyz[0]*input2xyz[2] - input1xyz[2]*input2xyz[0]));
      outputxyzOut.setValue(i*3 + 2, input1xyz[0]*input2xyz[1] - input1xyz[1]*input2xyz[0]);
    }

    // you also might want to do stuff like this:
    outputxyzOut.setSliceCount(Math.ceil(maxSize/3) * 3);
  }

}
VVVV.Nodes.Multiply3dCross.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Multiply (3d Dot)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Multiply3dDot = function(id, graph) {
  this.constructor(id, "Multiply (3d Dot)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var input1xyzIn = this.addInputPin('Input1 XYZ', [], this);
  var input2xyzIn = this.addInputPin('Input2 XYZ', [], this);

  // output pins
  var outputOut = this.addOutputPin('Output', [0], this);

  this.evaluate = function() {
    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var input1xyz = input1xyzIn.getValue(i, 3);
      var input2xyz = input2xyzIn.getValue(i, 3);

      outputOut.setValue(i, input1xyz[0]*input2xyz[0] + input1xyz[1]*input2xyz[1] + input1xyz[2]*input2xyz[2]);
    }

    outputOut.setSliceCount(Math.ceil(maxSize/3));
  }

}
VVVV.Nodes.Multiply3dDot.prototype = new VVVV.Core.Node();<commit_msg>adds * (3d Vector)<commit_after>// VVVV.js -- Visual Web Client Programming
// (c) 2011 Matthias Zauner
// VVVV.js is freely distributable under the MIT license.
// Additional authors of sub components are mentioned at the specific code locations.

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Polar (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Polar3d = function(id, graph) {
  this.constructor(id, "Polar (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xIn = this.addInputPin('X', [0], this);
  var yIn = this.addInputPin('Y', [0], this);
  var zIn = this.addInputPin('Z', [-1], this);

  // output pins
  var pitchOut = this.addOutputPin('Pitch', [0], this);
  var yawOut = this.addOutputPin('Yaw', [0], this);
  var lengthOut = this.addOutputPin('Length', [1], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var x = xIn.getValue(i);
      var y = yIn.getValue(i);
      var z = zIn.getValue(i);

      var len = Math.sqrt(x*x + y*y + z*z );

      yawOut.setValue(i, Math.atan2(-x, -z) / (2*Math.PI));
      pitchOut.setValue(i, len == 0 ? 0 : Math.acos(-y/len) / (2*Math.PI) - 0.25);
      lengthOut.setValue(i, len);
    }

    yawOut.setSliceCount(maxSize);
    pitchOut.setSliceCount(maxSize);
    lengthOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Polar3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Cartesian (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Cartesian3d = function(id, graph) {
  this.constructor(id, "Cartesian (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var pitchIn = this.addInputPin('Pitch', [0], this);
  var yawIn = this.addInputPin('Yaw', [0], this);
  var lengthIn = this.addInputPin('Length', [1], this);

  // output pins
  var xOut = this.addOutputPin('X', [0], this);
  var yOut = this.addOutputPin('Y', [0], this);
  var zOut = this.addOutputPin('Z', [1], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var pitch = (pitchIn.getValue(i) + 0.25) * 2 * Math.PI;
      var yaw = yawIn.getValue(i) * 2 * Math.PI;
      var length = lengthIn.getValue(i);

      zOut.setValue(i, -length * Math.cos(yaw) * Math.sin(pitch));
      xOut.setValue(i, -length * Math.sin(yaw) * Math.sin(pitch));
      yOut.setValue(i, -length * Math.cos(pitch));
    }

    xOut.setSliceCount(maxSize);
    yOut.setSliceCount(maxSize);
    zOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Cartesian3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Normalize (3d)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Normalize3d = function(id, graph) {
  this.constructor(id, "Normalize (3d)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xIn = this.addInputPin('X', [1], this);
  var yIn = this.addInputPin('Y', [0], this);
  var zIn = this.addInputPin('Z', [0], this);

  // output pins
  var normalizedxOut = this.addOutputPin('NormalizedX', [1], this);
  var normalizedyOut = this.addOutputPin('NormalizedY', [0], this);
  var normalizedzOut = this.addOutputPin('NormalizedZ', [0], this);
  var inputlengthOut = this.addOutputPin('Input Length', [0], this);

  this.evaluate = function() {

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize; i++) {
      var x = xIn.getValue(i);
      var y = yIn.getValue(i);
      var z = zIn.getValue(i);

      var len = Math.sqrt(x*x + y*y + z*z);

      normalizedxOut.setValue(i, len == 0 ? 0.0 : x / len);
      normalizedyOut.setValue(i, len == 0 ? 0.0 : y / len);
      normalizedzOut.setValue(i, len == 0 ? 0.0 : z / len);
      inputlengthOut.setValue(i, len);
    }

    normalizedxOut.setSliceCount(maxSize);
    normalizedyOut.setSliceCount(maxSize);
    normalizedzOut.setSliceCount(maxSize);
    inputlengthOut.setSliceCount(maxSize);
  }

}
VVVV.Nodes.Normalize3d.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Normalize (3d Vector)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Normalize3dVector = function(id, graph) {
  this.constructor(id, "Normalize (3d Vector)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var xyzIn = this.addInputPin('XYZ', [], this);

  // output pins
  var normalizedxyzOut = this.addOutputPin('NormalizedXYZ', [], this);
  var inputlengthOut = this.addOutputPin('Input Length', [0], this);

  this.evaluate = function() {

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var xyz = xyzIn.getValue(i, 3);

      var len = Math.sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1] + xyz[2]*xyz[2]);

      normalizedxyzOut.setValue(i*3, len == 0 ? 0.0 : xyz[0]/len);
      normalizedxyzOut.setValue(i*3 + 1, len == 0 ? 0.0 : xyz[1]/len);
      normalizedxyzOut.setValue(i*3 + 2, len == 0 ? 0.0 : xyz[2]/len);
      inputlengthOut.setValue(i, len);
    }

    normalizedxyzOut.setSliceCount(Math.ceil(maxSize/3) * 3);
    inputlengthOut.setSliceCount(Math.ceil(maxSize/3));
  }

}
VVVV.Nodes.Normalize3dVector.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Multiply (3d Cross)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Multiply3dCross = function(id, graph) {
  this.constructor(id, "Multiply (3d Cross)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var input1xyzIn = this.addInputPin('Input1 XYZ', [], this);
  var input2xyzIn = this.addInputPin('Input2 XYZ', [], this);

  // output pins
  var outputxyzOut = this.addOutputPin('Output XYZ', [], this);

  this.evaluate = function() {
    // to implement; maybe start with something like this:

    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var input1xyz = input1xyzIn.getValue(i, 3);
      var input2xyz = input2xyzIn.getValue(i, 3);

      outputxyzOut.setValue(i*3 + 0, input1xyz[1]*input2xyz[2] - input1xyz[2]*input2xyz[1]);
      outputxyzOut.setValue(i*3 + 1, -(input1xyz[0]*input2xyz[2] - input1xyz[2]*input2xyz[0]));
      outputxyzOut.setValue(i*3 + 2, input1xyz[0]*input2xyz[1] - input1xyz[1]*input2xyz[0]);
    }

    // you also might want to do stuff like this:
    outputxyzOut.setSliceCount(Math.ceil(maxSize/3) * 3);
  }

}
VVVV.Nodes.Multiply3dCross.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Multiply (3d Dot)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Multiply3dDot = function(id, graph) {
  this.constructor(id, "Multiply (3d Dot)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var input1xyzIn = this.addInputPin('Input1 XYZ', [], this);
  var input2xyzIn = this.addInputPin('Input2 XYZ', [], this);

  // output pins
  var outputOut = this.addOutputPin('Output', [0], this);

  this.evaluate = function() {
    var maxSize = this.getMaxInputSliceCount();

    for (var i=0; i<maxSize/3; i++) {
      var input1xyz = input1xyzIn.getValue(i, 3);
      var input2xyz = input2xyzIn.getValue(i, 3);

      outputOut.setValue(i, input1xyz[0]*input2xyz[0] + input1xyz[1]*input2xyz[1] + input1xyz[2]*input2xyz[2]);
    }

    outputOut.setSliceCount(Math.ceil(maxSize/3));
  }

}
VVVV.Nodes.Multiply3dDot.prototype = new VVVV.Core.Node();

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 NODE: Multiply (3d Vector)
 Author(s): 'Matthias Zauner'
 Original Node Author(s): 'VVVV Group'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/

VVVV.Nodes.Multiply3dVector = function(id, graph) {
  this.constructor(id, "Multiply (3d Vector)", graph);

  this.meta = {
    authors: ['Matthias Zauner'],
    original_authors: ['VVVV Group'],
    credits: [],
    compatibility_issues: []
  };

  this.auto_evaluate = false;

  // input pins
  var transformIn = this.addInputPin('Transform', [], this, true, VVVV.PinTypes.Transform);
  var xyzIn = this.addInputPin('XYZ UnTransformed', [0.0, 0.0, 0.0], this);

  // output pins
  var outputOut = this.addOutputPin('XYZ Transformed', [0.0, 0.0, 0.0], this);

  this.evaluate = function() {
    var maxSize = Math.max(transformIn.getSliceCount(), xyzIn.getSliceCount()/3);

    for (var i=0; i<maxSize; i++) {
      var xyz = xyzIn.getValue(i*3, 3);
      var t = transformIn.getValue(i);
      mat4.multiplyVec3(t, xyz);
      outputOut.setValue(i*3 + 0, xyz[0]);
      outputOut.setValue(i*3 + 1, xyz[1]);
      outputOut.setValue(i*3 + 2, xyz[2]);
    }

    outputOut.setSliceCount(Math.ceil(maxSize*3));
  }

}
VVVV.Nodes.Multiply3dVector.prototype = new VVVV.Core.Node();<|endoftext|>


<commit_before>'strict mode'

require('colors')

const { promisify } = require('util')
const fs = require('fs')
const path = require('path')
const fontGenerator = promisify(require('webfonts-generator'))
const {
  CSS_PARSE_REGEX, FONT_TYPES, TEMPLATES, OPTIONAL_PARAMS, DEFAULT_OPTIONS
} = require('./constants')
const { ValidationError } = require('./errors')
const { log, logOutput } = require('./utils')
const fsAsync = {
  exists    : promisify(fs.exists),
  stat      : promisify(fs.stat),
  unlink    : promisify(fs.unlink),
  readFile  : promisify(fs.readFile),
  writeFile : promisify(fs.writeFile)
}

/**
 * Generate icon font set asynchronously
 *
 * @param  {Object} options
 * @param  {Function} callback
 * @return {void}
 */
async function generate(options = {}) {
  options = Object.assign(DEFAULT_OPTIONS, options)

  // Log start
  let msg = `Generating font kit from ${ options.paths.length } SVG icons`.yellow
  log(options, msg)

  // Run validation over options
  await validateOptions(options)

  if (options.codepoints) {
    options.codepointsMap = await getCodepointsMap(options.codepoints)
  }

  // Run font generation
  const config = getGeneratorConfig(options)
  const generatorResult = await fontGenerator(config)

  // Clean up after generator
  await deleteUnspecifiedTypes(options)

  // If specified, generate JSON map
  if (options.json) {
    await generateJson(options, generatorResult)
  }

  // Log generated files
  logReport(options)
}

/**
 * Transform options Object in a configuration accepted by the generator
 *
 * @param  {Object} options
 * @return {void}
 */
function getGeneratorConfig(options) {
  const config = {
    files           : options.paths,
    dest            : options.outputDir,
    cssFontsUrl     : options.fontsPath,
    types           : options.types,
    codepoints      : options.codepointsMap,
    startCodepoint  : options.startCodepoint || 0xF101,
    cssDest         : options.cssPath,
    htmlDest        : options.htmlPath,
    cssTemplate     : options.cssTemplate  || TEMPLATES.css,
    htmlTemplate    : options.htmlTemplate || TEMPLATES.html,
    templateOptions : {
      baseTag     : options.templateOptions.baseTag || 'i',
      classPrefix : (options.templateOptions.classPrefix || 'icon') + '-'
    }
  }

  // Normalise and add available optional configurations
  OPTIONAL_PARAMS.forEach(key => {
    if (typeof options[key] !== 'undefined') {
      // Parse numeric values
      if (`${ parseFloat(options[key]) }` === `${ options[key] }`) {
        options[key] = parseFloat(options[key])
      }

      config[key] = options[key]
    }
  })

  return config
}

/**
 * Correctly parse codepoints map
 *
 * @param  {Object} options
 * @return {void}
 */
async function getCodepointsMap(filepath) {
  const content = await fsAsync.readFile(filepath)
  let codepointsMap

  try {
    codepointsMap = JSON.parse(content)
  } catch (e) {
    throw new ValidationError('Codepoints map is invalid JSON')
  }

  for (let propName in codepointsMap) {
    codepointsMap[propName] = Number.parseInt(codepointsMap[propName])
  }

  return codepointsMap
}

/**
 * Log report with all generated files and completion message
 *
 * @param  {Object} options
 * @return {void}
 */
function logReport(options) {
  const { outputDir, fontName } = options

  // Log font files output
  for (let ext of options.types) { logOutput(options, [ outputDir, `${ fontName }.${ ext }` ]) }

  // Log HTML file output
  if (options.html) {
    logOutput(options, [ outputDir, options.htmlPath || `${ fontName }.html` ])
  }

  // Log CSS file output
  if (options.css) {
    logOutput(options, [ outputDir, options.cssPath || `${ fontName }.css` ])
  }

  if (options.json) {
    // Log JSON map output
    logOutput(options, [ outputDir, options.jsonPath || `${ fontName }.json` ])
  }

  // Log final message
  log(options, 'Done'.green)
}

/**
 * Generate JSON icons map by parsing the generated CSS
 *
 * @param  {Object} options
 * @return {void}
 */
async function generateJson(options, generatorResult) {
  const jsonPath = (
    options.jsonPath ||
    `${ path.join(options.outputDir, '/' + options.fontName) }.json`
  )

  const css = generatorResult.generateCss()
  let map = {}

  css.replace(CSS_PARSE_REGEX, (match, name, code) => map[name] = code)

  await fsAsync.writeFile(jsonPath, JSON.stringify(map, null, 4))
}

/**
 * Delete generated fonts with extensions that weren't specified
 *
 * @param  {Object} options
 * @return {void}
 */
async function deleteUnspecifiedTypes(options) {
  const { outputDir, fontName, types } = options

  for (let ext of FONT_TYPES) {
    if (types.indexOf(ext) !== -1) { continue }

    let filepath = path.resolve(outputDir, `${ fontName }.${ ext }`)

    if (await fsAsync.exists(filepath)) {
      await fsAsync.unlink(filepath)
    }
  }
}

/**
 * Asynchronously validate generation options, check existance of given files
 * and directories
 *
 * @throws
 * @param  {Object} options
 * @return {void}
 */
async function validateOptions(options) {
  // Check that input glob was passed
  if (!options.paths.length) {
    throw new ValidationError('No paths specified')
  }

  // Check that output path was passed
  if (!options.outputDir) {
    throw new ValidationError('Please specify an output directory with -o or --output')
  }

  // Check that the existance of output path
  if (!await fsAsync.exists(options.outputDir)) {
    throw new ValidationError('Output directory doesn\'t exist')
  }

  // Check that output path is a directory
  const outStat = await fsAsync.stat(options.outputDir)
  if (!outStat.isDirectory()) {
    throw new ValidationError('Output path must be a directory')
  }

  // Check existance of CSS template (If set)
  if (options.cssTemplate && !await fsAsync.exists(options.cssTemplate)) {
    throw new ValidationError('CSS template not found')
  }

  // Check existance of HTML template (If set)
  if (options.htmlTemplate && !await fsAsync.exists(options.htmlTemplate)) {
    throw new ValidationError('HTML template not found')
  }

  // Validate codepoints file if passed
  if (options.codepoints) {
    if (!await fsAsync.exists(options.codepoints)) {
      throw new ValidationError(`Cannot find json file @ ${options.codepoints}!`)
    }

    const codepointsStat = await fsAsync.stat(options.codepoints)
    if (!codepointsStat.isFile() || path.extname(options.codepoints) !== '.json') {
      throw new ValidationError([
        'Codepoints file must be JSON',
        `${options.codepoints} is not a valid file.`
      ].join(' '))
    }
  }
}

module.exports = { generate }
<commit_msg>Fix broken assignment of templateOptions properties<commit_after>'strict mode'

require('colors')

const { promisify } = require('util')
const fs = require('fs')
const path = require('path')
const fontGenerator = promisify(require('webfonts-generator'))
const {
  CSS_PARSE_REGEX, FONT_TYPES, TEMPLATES, OPTIONAL_PARAMS, DEFAULT_OPTIONS
} = require('./constants')
const { ValidationError } = require('./errors')
const { log, logOutput } = require('./utils')
const fsAsync = {
  exists    : promisify(fs.exists),
  stat      : promisify(fs.stat),
  unlink    : promisify(fs.unlink),
  readFile  : promisify(fs.readFile),
  writeFile : promisify(fs.writeFile)
}

/**
 * Generate icon font set asynchronously
 *
 * @param  {Object} options
 * @param  {Function} callback
 * @return {void}
 */
async function generate(options = {}) {
  options = Object.assign(DEFAULT_OPTIONS, options)

  // Log start
  let msg = `Generating font kit from ${ options.paths.length } SVG icons`.yellow
  log(options, msg)

  // Run validation over options
  await validateOptions(options)

  if (options.codepoints) {
    options.codepointsMap = await getCodepointsMap(options.codepoints)
  }

  // Run font generation
  const config = getGeneratorConfig(options)
  const generatorResult = await fontGenerator(config)

  // Clean up after generator
  await deleteUnspecifiedTypes(options)

  // If specified, generate JSON map
  if (options.json) {
    await generateJson(options, generatorResult)
  }

  // Log generated files
  logReport(options)
}

/**
 * Transform options Object in a configuration accepted by the generator
 *
 * @param  {Object} options
 * @return {void}
 */
function getGeneratorConfig(options) {
  const config = {
    files           : options.paths,
    dest            : options.outputDir,
    cssFontsUrl     : options.fontsPath,
    types           : options.types,
    codepoints      : options.codepointsMap,
    startCodepoint  : options.startCodepoint || 0xF101,
    cssDest         : options.cssPath,
    htmlDest        : options.htmlPath,
    cssTemplate     : options.cssTemplate  || TEMPLATES.css,
    htmlTemplate    : options.htmlTemplate || TEMPLATES.html,
    templateOptions : {
      baseTag     : options.baseTag || 'i',
      classPrefix : (options.classPrefix || 'icon') + '-'
    }
  }

  // Normalise and add available optional configurations
  OPTIONAL_PARAMS.forEach(key => {
    if (typeof options[key] !== 'undefined') {
      // Parse numeric values
      if (`${ parseFloat(options[key]) }` === `${ options[key] }`) {
        options[key] = parseFloat(options[key])
      }

      config[key] = options[key]
    }
  })

  return config
}

/**
 * Correctly parse codepoints map
 *
 * @param  {Object} options
 * @return {void}
 */
async function getCodepointsMap(filepath) {
  const content = await fsAsync.readFile(filepath)
  let codepointsMap

  try {
    codepointsMap = JSON.parse(content)
  } catch (e) {
    throw new ValidationError('Codepoints map is invalid JSON')
  }

  for (let propName in codepointsMap) {
    codepointsMap[propName] = Number.parseInt(codepointsMap[propName])
  }

  return codepointsMap
}

/**
 * Log report with all generated files and completion message
 *
 * @param  {Object} options
 * @return {void}
 */
function logReport(options) {
  const { outputDir, fontName } = options

  // Log font files output
  for (let ext of options.types) { logOutput(options, [ outputDir, `${ fontName }.${ ext }` ]) }

  // Log HTML file output
  if (options.html) {
    logOutput(options, [ outputDir, options.htmlPath || `${ fontName }.html` ])
  }

  // Log CSS file output
  if (options.css) {
    logOutput(options, [ outputDir, options.cssPath || `${ fontName }.css` ])
  }

  if (options.json) {
    // Log JSON map output
    logOutput(options, [ outputDir, options.jsonPath || `${ fontName }.json` ])
  }

  // Log final message
  log(options, 'Done'.green)
}

/**
 * Generate JSON icons map by parsing the generated CSS
 *
 * @param  {Object} options
 * @return {void}
 */
async function generateJson(options, generatorResult) {
  const jsonPath = (
    options.jsonPath ||
    `${ path.join(options.outputDir, '/' + options.fontName) }.json`
  )

  const css = generatorResult.generateCss()
  let map = {}

  css.replace(CSS_PARSE_REGEX, (match, name, code) => map[name] = code)

  await fsAsync.writeFile(jsonPath, JSON.stringify(map, null, 4))
}

/**
 * Delete generated fonts with extensions that weren't specified
 *
 * @param  {Object} options
 * @return {void}
 */
async function deleteUnspecifiedTypes(options) {
  const { outputDir, fontName, types } = options

  for (let ext of FONT_TYPES) {
    if (types.indexOf(ext) !== -1) { continue }

    let filepath = path.resolve(outputDir, `${ fontName }.${ ext }`)

    if (await fsAsync.exists(filepath)) {
      await fsAsync.unlink(filepath)
    }
  }
}

/**
 * Asynchronously validate generation options, check existance of given files
 * and directories
 *
 * @throws
 * @param  {Object} options
 * @return {void}
 */
async function validateOptions(options) {
  // Check that input glob was passed
  if (!options.paths.length) {
    throw new ValidationError('No paths specified')
  }

  // Check that output path was passed
  if (!options.outputDir) {
    throw new ValidationError('Please specify an output directory with -o or --output')
  }

  // Check that the existance of output path
  if (!await fsAsync.exists(options.outputDir)) {
    throw new ValidationError('Output directory doesn\'t exist')
  }

  // Check that output path is a directory
  const outStat = await fsAsync.stat(options.outputDir)
  if (!outStat.isDirectory()) {
    throw new ValidationError('Output path must be a directory')
  }

  // Check existance of CSS template (If set)
  if (options.cssTemplate && !await fsAsync.exists(options.cssTemplate)) {
    throw new ValidationError('CSS template not found')
  }

  // Check existance of HTML template (If set)
  if (options.htmlTemplate && !await fsAsync.exists(options.htmlTemplate)) {
    throw new ValidationError('HTML template not found')
  }

  // Validate codepoints file if passed
  if (options.codepoints) {
    if (!await fsAsync.exists(options.codepoints)) {
      throw new ValidationError(`Cannot find json file @ ${options.codepoints}!`)
    }

    const codepointsStat = await fsAsync.stat(options.codepoints)
    if (!codepointsStat.isFile() || path.extname(options.codepoints) !== '.json') {
      throw new ValidationError([
        'Codepoints file must be JSON',
        `${options.codepoints} is not a valid file.`
      ].join(' '))
    }
  }
}

module.exports = { generate }
<|endoftext|>


<commit_before>var   gulp         = require('gulp')
    , notify       = require("gulp-notify")
    , csso         = require('gulp-csso')
    , uglify       = require('gulp-uglify')
    , connect      = require('gulp-connect')
    , compass      = require('gulp-for-compass')
    , concat       = require('gulp-concat')
    , autoprefixer = require('gulp-autoprefixer')
    , imageminJpegtran = require('imagemin-jpegtran')
    , imageminPngquant = require('imagemin-pngquant')
    , imageResize = require('gulp-image-resize')
    ;

//server
gulp.task('server', function() {
    connect.server({
        livereload: true
    });
});

//html
gulp.task('html',function(){
    gulp.src('index.html')
        .pipe(connect.reload())
        .pipe(notify("Change index.html"));
});

//css
gulp.task('css',function(){
    gulp.src('style.css')
        .pipe(connect.reload());
});

//js
gulp.task('js', function() {
    gulp.src('./lib/js/**/*.js')
        .pipe(connect.reload());
});

//compress pic
gulp.task('compress-image', function () {
    gulp.src('./lib/**.jpg')
        .pipe(imageminJpegtran({progressive: true})())
        .pipe(gulp.dest('./build/lib/'));

    gulp.src('./lib/pic/**')
        .pipe(imageResize({ width : 1280 }))
        .pipe(gulp.dest('./build/lib/pic/'));

    gulp.src('./lib/image/**')
        .pipe(imageResize({ width : 300 }))
        .pipe(imageminJpegtran({progressive: true})())
        .pipe(imageminPngquant({quality: '65-80', speed: 4})())
        .pipe(gulp.dest('./build/lib/image/'));
});

//sass
gulp.task('sass', function(){
    gulp.src('./lib/sass/**/*.sass')
        .pipe(compass({
            httpFontsPath:  '../font/',
            httpGeneratedImagesPath: '../pic/',
            cssDir:    './lib/css/',
            sassDir:   './lib/sass/',
            fontsDir:  './lib/font/',
            imagesDir: './lib/pic/',
            force: true
        }))
        .pipe(connect.reload())
        .pipe(notify("Compile SASS"));
});

//concat
gulp.task('concat-js', function() {
    return gulp.src([
            './lib/js/owl.carousel.js',
            //'./lib/js/jquery.stellar.js',
            //'./lib/js/jquery.appear.js',
            './lib/js/app.js',
            './lib/js/map.js'
        ])
        .pipe(concat('app.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('./lib/js/'));
});

//watch
gulp.task('watch', function () {
    gulp.watch('./index.html', ['html']);
    gulp.watch('./lib/sass/**/*', ['sass']);
    gulp.watch('./lib/css/**/*', ['css']);
    gulp.watch('./lib/js/**/*', ['concat-js', 'js']);
});

//compress css
gulp.task('compress-css', function() {
    return gulp.src('./lib/css/style.css')
        .pipe(autoprefixer({
            browsers: ['last 10 versions'],
            cascade: false
        }))
        .pipe(csso())
        .pipe(gulp.dest('./build/lib/css/'));
});

//compress js
//gulp.task('compress-js', function() {
//    gulp.src('./public/js/*')
//        .pipe(uglify())
//        .pipe(gulp.dest('./public/js/'))
//});

gulp.task('copy-src',['build-static', 'compress-css', 'compress-image'],function() {
  gulp.src(['./index.html','./favicon.*'])
    .pipe(gulp.dest('./build'))
  gulp.src(['./lib/font/*'])
    .pipe(gulp.dest('./build/lib/font'))
  gulp.src(['./lib/css/*'])
    .pipe(gulp.dest('./build/lib/css'))
  gulp.src(['./lib/js/app.min.js'])
    .pipe(gulp.dest('./build/lib/js'))
});

gulp.task('build-static', ['sass', 'css', 'js', 'concat-js']);
gulp.task('default', ['server', 'html', 'build-static', 'watch']);
gulp.task('production', ['build-static', 'copy-src']);
<commit_msg>Sponsors v1.0<commit_after>var   gulp         = require('gulp')
    , notify       = require("gulp-notify")
    , csso         = require('gulp-csso')
    , uglify       = require('gulp-uglify')
    , connect      = require('gulp-connect')
    , compass      = require('gulp-for-compass')
    , concat       = require('gulp-concat')
    , autoprefixer = require('gulp-autoprefixer')
    , imageminJpegtran = require('imagemin-jpegtran')
    , imageminPngquant = require('imagemin-pngquant')
    , imageResize = require('gulp-image-resize')
    ;

//server
gulp.task('server', function() {
    connect.server({
        livereload: true
    });
});

//html
gulp.task('html',function(){
    gulp.src('index.html')
        .pipe(connect.reload())
        .pipe(notify("Change index.html"));
    gulp.src('sponsors.html')
        .pipe(connect.reload())
        .pipe(notify("Change sponsors.html"));
});

//css
gulp.task('css',function(){
    gulp.src('style.css')
        .pipe(connect.reload());
});

//js
gulp.task('js', function() {
    gulp.src('./lib/js/**/*.js')
        .pipe(connect.reload());
});

//compress pic
gulp.task('compress-image', function () {
    gulp.src('./lib/**.jpg')
        .pipe(imageminJpegtran({progressive: true})())
        .pipe(gulp.dest('./build/lib/'));

    gulp.src('./lib/pic/**')
        .pipe(imageResize({ width : 1280 }))
        .pipe(gulp.dest('./build/lib/pic/'));

    gulp.src('./lib/image/**')
        .pipe(imageResize({ width : 300 }))
        .pipe(imageminJpegtran({progressive: true})())
        .pipe(imageminPngquant({quality: '65-80', speed: 4})())
        .pipe(gulp.dest('./build/lib/image/'));
});

//sass
gulp.task('sass', function(){
    gulp.src('./lib/sass/**/*.sass')
        .pipe(compass({
            httpFontsPath:  '../font/',
            httpGeneratedImagesPath: '../pic/',
            cssDir:    './lib/css/',
            sassDir:   './lib/sass/',
            fontsDir:  './lib/font/',
            imagesDir: './lib/pic/',
            force: true
        }))
        .pipe(connect.reload())
        .pipe(notify("Compile SASS"));
});

//concat
gulp.task('concat-js', function() {
    return gulp.src([
            './lib/js/owl.carousel.js',
            //'./lib/js/jquery.stellar.js',
            //'./lib/js/jquery.appear.js',
            './lib/js/app.js',
            './lib/js/map.js'
        ])
        .pipe(concat('app.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('./lib/js/'));
});

//watch
gulp.task('watch', function () {
    gulp.watch('./index.html', ['html']);
    gulp.watch('./lib/sass/**/*', ['sass']);
    gulp.watch('./lib/css/**/*', ['css']);
    gulp.watch('./lib/js/**/*', ['concat-js', 'js']);
});

//compress css
gulp.task('compress-css', function() {
    return gulp.src('./lib/css/style.css')
        .pipe(autoprefixer({
            browsers: ['last 10 versions'],
            cascade: false
        }))
        .pipe(csso())
        .pipe(gulp.dest('./build/lib/css/'));
});

//compress js
//gulp.task('compress-js', function() {
//    gulp.src('./public/js/*')
//        .pipe(uglify())
//        .pipe(gulp.dest('./public/js/'))
//});

gulp.task('copy-src',['build-static', 'compress-css', 'compress-image'],function() {
  gulp.src(['./index.html','./favicon.*'])
    .pipe(gulp.dest('./build'))
  gulp.src(['./lib/font/*'])
    .pipe(gulp.dest('./build/lib/font'))
  gulp.src(['./lib/css/*'])
    .pipe(gulp.dest('./build/lib/css'))
  gulp.src(['./lib/js/app.min.js'])
    .pipe(gulp.dest('./build/lib/js'))
});

gulp.task('build-static', ['sass', 'css', 'js', 'concat-js']);
gulp.task('default', ['server', 'html', 'build-static', 'watch']);
gulp.task('production', ['build-static', 'copy-src']);
<|endoftext|>