<commit_before>namespace('Sy');

Sy.service = new Sy.ServiceContainer('sy::core');

Sy.service.set('sy::core::generator::uuid', function () {

    return new Sy.Lib.Generator.UUID();

});

Sy.service.set('sy::core::mediator', function () {

    var m = new Sy.Lib.Mediator();

    m.setGenerator(Sy.service.get('sy::core::generator::uuid'));
    m.setLogger(Sy.service.get('sy::core::logger'));

    return m;

});

Sy.service.set('sy::core::logger', function () {

    var logger = new Sy.Lib.Logger.CoreLogger('core'),
        info = new Sy.Lib.Logger.Handler.Console(logger.INFO),
        debug = new Sy.Lib.Logger.Handler.Console(logger.DEBUG),
        error = new Sy.Lib.Logger.Handler.Console(logger.ERROR),
        log = new Sy.Lib.Logger.Handler.Console(logger.LOG);

    logger.setHandler(info, logger.INFO);
    logger.setHandler(debug, logger.DEBUG);
    logger.setHandler(error, logger.ERROR);
    logger.setHandler(log, logger.LOG);

    return logger;

});

Sy.service.set('sy::core::http', function () {

    var parser = new Sy.HTTP.HeaderParser(),
        manager = new Sy.HTTP.Manager();

    manager.setParser(parser);
    manager.setGenerator(Sy.service.get('sy::core::generator::uuid'));

    return manager;

});

Sy.service.set('sy::core::http::rest', function () {

    var rest = new Sy.HTTP.REST();

    rest.setManager(Sy.service.get('sy::core::http'));

    return rest;

});

Sy.service.set('sy::core::storage', function () {

    var meta = [
            {
                name: 'DefaultBundle::Todo',
                repository: Sy.Storage.Repository,
                entity: App.Bundle.DefaultBundle.Entity.Todo,
                indexes: [],
                uuid: 'uuid'
            }
        ],
        storage = new Sy.Storage.Core(),
        managerFact = new Sy.Storage.ManagerFactory(),
        repositoryFact = new Sy.Storage.RepositoryFactory(),
        engineFact = new Sy.Storage.EngineFactory(),
        conf = Sy.config.get('storage');

    repositoryFact
        .setMetaRegistry(new Sy.Registry())
        .setRepoRegistry(new Sy.Registry())
        .setMeta(meta)
        .setGenerator(Sy.service.get('sy::core::generator::uuid'));

    for (var engineName in conf.engines) {
        if (conf.engines.hasOwnProperty(engineName)) {
            engineFact.setEngine(engineName, conf.engines[engineName]);
        }
    }

    managerFact
        .setEngineFactory(engineFact)
        .setRepositoryFactory(repositoryFact);

    for (var name in conf.managers) {
        if (conf.managers.hasOwnProperty(name)) {
            var manager = managerFact.make(name, conf.managers[name], meta);

            storage.setManager(name, manager);
        }
    }

    return storage;

});

Sy.config = new Sy.Configurator();

Sy.config.set({
    env: 'prod',
    storage: {
        engines: {
            rest: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Rest(version);

                engine.setManager(Sy.service.get('sy::core::http::rest'));
                engine.setPattern('/api/{{version}}/{{path}}/{{key}}');

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase().replace('::', '/'),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                return engine;

            },
            indexeddb: function (version, entitiesMeta) {

                var engine =  new Sy.Storage.Engine.IndexedDB(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                engine
                    .setConnection(
                        window.indexedDB ||
                        window.webkitIndexedDB ||
                        window.mozIndexedDB ||
                        window.msIndexedDB
                    )
                    .setTransaction(
                        window.IDBTransaction ||
                        window.webkitIDBTransaction
                    )
                    .setKeyRange(
                        window.IDBKeyRange ||
                        window.webkitIDBKeyRange
                    )
                    .setLogger(
                        Sy.service.get('sy::core::logger')
                    )
                    .open();

                return engine;

            },
            localstorage: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Localstorage(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                engine.setStorage(window.localStorage);
                engine.open();

                return engine;

            },
            memory: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Memory(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                return engine;

            }
        }
    }
});<commit_msg>#6 added the UUID as index for indexeddb so the dev can do a findby on uuid with an empty string as lower bound to get all objects<commit_after>namespace('Sy');

Sy.service = new Sy.ServiceContainer('sy::core');

Sy.service.set('sy::core::generator::uuid', function () {

    return new Sy.Lib.Generator.UUID();

});

Sy.service.set('sy::core::mediator', function () {

    var m = new Sy.Lib.Mediator();

    m.setGenerator(Sy.service.get('sy::core::generator::uuid'));
    m.setLogger(Sy.service.get('sy::core::logger'));

    return m;

});

Sy.service.set('sy::core::logger', function () {

    var logger = new Sy.Lib.Logger.CoreLogger('core'),
        info = new Sy.Lib.Logger.Handler.Console(logger.INFO),
        debug = new Sy.Lib.Logger.Handler.Console(logger.DEBUG),
        error = new Sy.Lib.Logger.Handler.Console(logger.ERROR),
        log = new Sy.Lib.Logger.Handler.Console(logger.LOG);

    logger.setHandler(info, logger.INFO);
    logger.setHandler(debug, logger.DEBUG);
    logger.setHandler(error, logger.ERROR);
    logger.setHandler(log, logger.LOG);

    return logger;

});

Sy.service.set('sy::core::http', function () {

    var parser = new Sy.HTTP.HeaderParser(),
        manager = new Sy.HTTP.Manager();

    manager.setParser(parser);
    manager.setGenerator(Sy.service.get('sy::core::generator::uuid'));

    return manager;

});

Sy.service.set('sy::core::http::rest', function () {

    var rest = new Sy.HTTP.REST();

    rest.setManager(Sy.service.get('sy::core::http'));

    return rest;

});

Sy.service.set('sy::core::storage', function () {

    var meta = [
            {
                name: 'DefaultBundle::Todo',
                repository: Sy.Storage.Repository,
                entity: App.Bundle.DefaultBundle.Entity.Todo,
                indexes: [],
                uuid: 'uuid'
            }
        ],
        storage = new Sy.Storage.Core(),
        managerFact = new Sy.Storage.ManagerFactory(),
        repositoryFact = new Sy.Storage.RepositoryFactory(),
        engineFact = new Sy.Storage.EngineFactory(),
        conf = Sy.config.get('storage');

    repositoryFact
        .setMetaRegistry(new Sy.Registry())
        .setRepoRegistry(new Sy.Registry())
        .setMeta(meta)
        .setGenerator(Sy.service.get('sy::core::generator::uuid'));

    for (var engineName in conf.engines) {
        if (conf.engines.hasOwnProperty(engineName)) {
            engineFact.setEngine(engineName, conf.engines[engineName]);
        }
    }

    managerFact
        .setEngineFactory(engineFact)
        .setRepositoryFactory(repositoryFact);

    for (var name in conf.managers) {
        if (conf.managers.hasOwnProperty(name)) {
            var manager = managerFact.make(name, conf.managers[name], meta);

            storage.setManager(name, manager);
        }
    }

    return storage;

});

Sy.config = new Sy.Configurator();

Sy.config.set({
    env: 'prod',
    storage: {
        engines: {
            rest: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Rest(version);

                engine.setManager(Sy.service.get('sy::core::http::rest'));
                engine.setPattern('/api/{{version}}/{{path}}/{{key}}');

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase().replace('::', '/'),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                return engine;

            },
            indexeddb: function (version, entitiesMeta) {

                var engine =  new Sy.Storage.Engine.IndexedDB(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes.concat(entitiesMeta[i].uuid)
                    );
                }

                engine
                    .setConnection(
                        window.indexedDB ||
                        window.webkitIndexedDB ||
                        window.mozIndexedDB ||
                        window.msIndexedDB
                    )
                    .setTransaction(
                        window.IDBTransaction ||
                        window.webkitIDBTransaction
                    )
                    .setKeyRange(
                        window.IDBKeyRange ||
                        window.webkitIDBKeyRange
                    )
                    .setLogger(
                        Sy.service.get('sy::core::logger')
                    )
                    .open();

                return engine;

            },
            localstorage: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Localstorage(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                engine.setStorage(window.localStorage);
                engine.open();

                return engine;

            },
            memory: function (version, entitiesMeta) {

                var engine = new Sy.Storage.Engine.Memory(version);

                for (var i = 0, l = entitiesMeta.length; i < l; i++) {
                    engine.setStore(
                        entitiesMeta[i].name,
                        entitiesMeta[i].name.toLowerCase(),
                        entitiesMeta[i].uuid,
                        entitiesMeta[i].indexes
                    );
                }

                return engine;

            }
        }
    }
});<|endoftext|>


<commit_before>export default function (data) {
  return data.days.map(day => {
    let topicTimeMap = {}
    day.rooms.forEach(room => {
      room.topics.forEach(topic => {
        if (!topicTimeMap[topic.start_at]) {
          topicTimeMap[topic.start_at] = []
        }
        if (!(topic.rest && topicTimeMap[topic.start_at].length === 1)) {
          topic.room = room
          topic.isSubscribed = false
          topicTimeMap[topic.start_at].push(topic)
        }
      })
    })
    day.topics = topicTimeMap
    delete day.rooms
    return day
  })
}

export function combineData (days, subscription) {
  return days.map(day => {
    const newTopics = {}
    for (let sectionID in day.topics) {
      let section = day.topics[sectionID].map(
        topic => {
          return {
            ...topic,
            isSubscribed: subscription.indexOf(topic.id) > -1
          }
        })
      day.topics[sectionID] = section
      newTopics[sectionID] = section
    }
    return {...day, topics: newTopics}
  })
}
<commit_msg>add genSubscribedData in dataHelper<commit_after>export function genData (data) {
  return data.days.map(day => {
    let topicTimeMap = {}
    day.rooms.forEach(room => {
      room.topics.forEach(topic => {
        if (!topicTimeMap[topic.start_at]) {
          topicTimeMap[topic.start_at] = []
        }
        if (!(topic.rest && topicTimeMap[topic.start_at].length === 1)) {
          topic.room = room
          topic.isSubscribed = false
          topicTimeMap[topic.start_at].push(topic)
        }
      })
    })
    day.topics = topicTimeMap
    delete day.rooms
    return day
  })
}

/*
 * 潜在Bug: 组合数据时，一定要返回一个新的对象。(days是一个不可变的源数据)
 * 否则，第一次调用，ListView接收到的是被修改了的原始数据。后期则是一直使用对原始数据的修改。
 * 因此，在每次调用的时候，一定要返回一个新的对象，以供ListView的WillReceiveProps做对比
 */
export function combineData (days, subscription) {
  return days.map(day => {
    const newTopics = {}
    for (let sectionID in day.topics) {
      let section = day.topics[sectionID].map(
        topic => ({
          ...topic,
          isSubscribed: subscription.indexOf(topic.id) > -1
        })
      )
      newTopics[sectionID] = section
    }
    return {...day, topics: newTopics}
  })
}

// [{..., topics: {1: [], 2: []}}, {}]
export function genSubscribedData (days, subscription) {
  let result = {}
  days.forEach(day => {
    for (let sectionID in day.topics) {
      day.topics[sectionID].forEach(topic => {
        if (subscription.indexOf(topic.id) > -1) {
          if (!result[day.id]) {
            result[day.id] = []
          }
          result[day.id].push(topic)
        }
      })
    }
  })
  console.log('result: ', result)
  return result
}
<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var Clock = require('../src/Clock');

test('Clock', function(t) {
    t.test('constructor', function(t) {
        t.plan(1);
        t.doesNotThrow(function() {
            new Clock();
        }, 'Clock constructor should not be a function');
    });

    t.test('step method', function(t) {
        t.plan(3);
        var clock = new Clock();
        t.equal(typeof clock.step, 'function', 'clock.step should be a function');

        t.equal(clock.step(123), clock, 'clock.step should be chainable');
        t.equal(clock.getTime(), 123, 'clock.step should update internal time');
    });

    t.test('getTime method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).getTime, 'function', 'clock.getTime should be a function');
    });

    t.test('now method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).now, 'function', 'clock.now should be a function');
    });

    t.test('getFrame method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).getFrame, 'function', 'clock.getFrame should be a function');
    });

    t.test('setTimeout method (basic)', function(t) {
        t.plan(6);
        var clock = new Clock();
        t.equal(typeof clock.setTimeout, 'function', 'clock.setTimeout should be a function');
        var invoked = false;
        clock.setTimeout(function() {
            invoked = true;
        }, 1000);
        clock.step(500);
        t.equal(invoked, false, 'clock should not invoke passed in timer function after 500ms');
        clock.step(750);
        t.equal(invoked, false, 'clock should not invoke passed in timer function after 750ms');
        clock.step(1000);
        t.equal(invoked, true, 'clock should invoke passed in timer function after 1000ms');
        invoked = false;
        clock.step(1000);
        t.equal(invoked, false, 'clock should invoke passed in timer function only once');
        clock.step(1001);
        t.equal(invoked, false, 'clock should invoke passed in timer function only once');
    });

    t.test('setTimeout method (multiple sequential functions)', function(t) {
        var clock = new Clock();
        var timerFunctions = [];
        var time = 0;
        var i;
        for (i = 10; i < 20; i++) {
            clock.setTimeout(function(i) {
                if (time < i) {
                    t.fail(i + '. timeout function has been invoked at ' + time);
                }
            }.bind(null, i), i);
        }
        for (i = 0; i < 20; i++) {
            time = i;
            clock.step(i);
        }
        t.end();
    });

    t.test('setTimeout method (order of invokcations)', function(t) {
        t.plan(2);
        var clock = new Clock();
        var first = false;
        var second = false;
        clock.setTimeout(function() {
            if (second) {
                t.fail('clock.setTimeout invoked second scheduled timer function before first one');
            } else {
                t.pass('clock.setTimeout invoked first scheduled timer function before second one');
            }
            first = true;
        }, 10);
        clock.setTimeout(function() {
            if (!first) {
                t.fail('clock.setTimeout invoked second scheduled timer function before first one');
            } else {
                t.pass('clock.setTimeout invoked first scheduled timer function before second one');
            }
            second = true;
        }, 10);
        clock.step(10);
        clock.step(12);
    });

    t.test('setInterval method (basic)', function(t) {
        t.plan(2);
        var clock = new Clock();
        t.equal(typeof clock.setInterval, 'function', 'clock.setInterval should be a function');
        var time = 0;
        var invocations = [];
        clock.setInterval(function() {
            invocations.push(time);
        }, 7);
        for (time = 0; time < 100; time++) {
            clock.step(time);
        }
        t.deepEqual(
            invocations,
            [ 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98 ],
            'callback should have been invoked every 7 steps'
        );
    });

    t.test('clearTimer function', function(t) {
        var clock = new Clock();
        t.equal(typeof clock.clearTimer, 'function', 'clock.clearTimer should be a function');
        var timeout = clock.setTimeout(function() {
            t.fail('clock.clearTimer should cancel future invocation of timer function');
        }, 100);
        var interval = clock.setInterval(function() {
            t.fail('clock.clearTimer should cancel future invocation of timer function');
        }, 100);

        clock.step(50);
        clock.clearTimer(timeout);
        clock.clearTimer(interval);
        clock.step(75);
        clock.step(100);
        clock.step(101);
        t.end();
    });
});
<commit_msg>test: Test Clock#setScale, Clock#getScale [#93723694]<commit_after>'use strict';

var test = require('tape');
var Clock = require('../src/Clock');

test('Clock', function(t) {
    t.test('constructor', function(t) {
        t.plan(1);
        t.doesNotThrow(function() {
            new Clock();
        }, 'Clock constructor should not be a function');
    });

    t.test('step method', function(t) {
        t.plan(3);
        var clock = new Clock();
        t.equal(typeof clock.step, 'function', 'clock.step should be a function');

        t.equal(clock.step(123), clock, 'clock.step should be chainable');
        t.equal(clock.getTime(), 123, 'clock.step should update internal time');
    });

    t.test('getTime method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).getTime, 'function', 'clock.getTime should be a function');
    });

    t.test('now method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).now, 'function', 'clock.now should be a function');
    });

    t.test('getFrame method', function(t) {
        t.plan(1);
        t.equal(typeof (new Clock()).getFrame, 'function', 'clock.getFrame should be a function');
    });

    t.test('setTimeout method (basic)', function(t) {
        t.plan(6);
        var clock = new Clock();
        t.equal(typeof clock.setTimeout, 'function', 'clock.setTimeout should be a function');
        var invoked = false;
        clock.setTimeout(function() {
            invoked = true;
        }, 1000);
        clock.step(500);
        t.equal(invoked, false, 'clock should not invoke passed in timer function after 500ms');
        clock.step(750);
        t.equal(invoked, false, 'clock should not invoke passed in timer function after 750ms');
        clock.step(1000);
        t.equal(invoked, true, 'clock should invoke passed in timer function after 1000ms');
        invoked = false;
        clock.step(1000);
        t.equal(invoked, false, 'clock should invoke passed in timer function only once');
        clock.step(1001);
        t.equal(invoked, false, 'clock should invoke passed in timer function only once');
    });

    t.test('setTimeout method (multiple sequential functions)', function(t) {
        var clock = new Clock();
        var timerFunctions = [];
        var time = 0;
        var i;
        for (i = 10; i < 20; i++) {
            clock.setTimeout(function(i) {
                if (time < i) {
                    t.fail(i + '. timeout function has been invoked at ' + time);
                }
            }.bind(null, i), i);
        }
        for (i = 0; i < 20; i++) {
            time = i;
            clock.step(i);
        }
        t.end();
    });

    t.test('setTimeout method (order of invokcations)', function(t) {
        t.plan(2);
        var clock = new Clock();
        var first = false;
        var second = false;
        clock.setTimeout(function() {
            if (second) {
                t.fail('clock.setTimeout invoked second scheduled timer function before first one');
            } else {
                t.pass('clock.setTimeout invoked first scheduled timer function before second one');
            }
            first = true;
        }, 10);
        clock.setTimeout(function() {
            if (!first) {
                t.fail('clock.setTimeout invoked second scheduled timer function before first one');
            } else {
                t.pass('clock.setTimeout invoked first scheduled timer function before second one');
            }
            second = true;
        }, 10);
        clock.step(10);
        clock.step(12);
    });

    t.test('setInterval method (basic)', function(t) {
        t.plan(2);
        var clock = new Clock();
        t.equal(typeof clock.setInterval, 'function', 'clock.setInterval should be a function');
        var time = 0;
        var invocations = [];
        clock.setInterval(function() {
            invocations.push(time);
        }, 7);
        for (time = 0; time < 100; time++) {
            clock.step(time);
        }
        t.deepEqual(
            invocations,
            [ 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98 ],
            'callback should have been invoked every 7 steps'
        );
    });

    t.test('clearTimer function', function(t) {
        var clock = new Clock();
        t.equal(typeof clock.clearTimer, 'function', 'clock.clearTimer should be a function');
        var timeout = clock.setTimeout(function() {
            t.fail('clock.clearTimer should cancel future invocation of timer function');
        }, 100);
        var interval = clock.setInterval(function() {
            t.fail('clock.clearTimer should cancel future invocation of timer function');
        }, 100);

        clock.step(50);
        clock.clearTimer(timeout);
        clock.clearTimer(interval);
        clock.step(75);
        clock.step(100);
        clock.step(101);
        t.end();
    });

    t.test('setScale/ getScale method', function(t) {
        var clock = new Clock();
        t.equal(typeof clock.setScale, 'function', 'clock.setScale should be a function');
        t.equal(typeof clock.getScale, 'function', 'clock.getScale should be a function');

        clock.step(100);
        t.equal(clock.now(), 100);

        t.equal(clock.getScale(), 1, 'Clock should be initialized with a time scale of 1 (realtime)');

        clock.step(120);
        t.equal(clock.now(), 120);
        clock.setScale(0.5);
        t.equal(clock.getScale(), 0.5);
        t.equal(clock.now(), 120);

        clock.step(150);
        t.equal(clock.now(), 135);

        clock.step(210);
        t.equal(clock.now(), 165);

        clock.setScale(1);
        t.equal(clock.getScale(), 1);
        clock.step(220);
        t.equal(clock.now(), 175);

        t.end();
    });
});
<|endoftext|>


<commit_before>#!/usr/bin/node

// Reads the package.json of a Stripes module, and writes out a
// corresponding ModuleDescriptor.md
// e.g. node package2md.js ../../ui-users/package.json

const fs = require('fs');

const argv1 = process.argv[1].replace(/.*\//, '');

let strict = false;
if (process.argv[2] === '--strict') {
  process.argv.shift();
  strict = true;
}

const filename = process.argv[2];
if (!filename) {
  console.log(`Usage: ${argv1} <package-file>`);
  process.exit(1);
}

fs.readFile(filename, 'utf8', (err, data) => { // eslint-disable-line consistent-return
  if (err) {
    return console.log(`${argv1}: cannot read file '${filename}': ${err}`);
  }

  const json = JSON.parse(data);
  const stripes = json.stripes || {};
  const interfaces = stripes.okapiInterfaces || [];
  const md = {
    id: `${json.name.replace(/^@/, '').replace('/', '_')}-${json.version}`,
    name: json.description,
    permissionSets: stripes.permissionSets || [],
  };
  if (strict) md.requires = Object.keys(interfaces).map(key => ({ id: key, version: interfaces[key] }));

  console.log(JSON.stringify(md, undefined, 2));
});
<commit_msg>Okapi 509  optional dependencies (#819)<commit_after>#!/usr/bin/node

// Reads the package.json of a Stripes module, and writes out a
// corresponding ModuleDescriptor.md
// e.g. node package2md.js ../../ui-users/package.json

const fs = require('fs');

const argv1 = process.argv[1].replace(/.*\//, '');

let strict = false;
if (process.argv[2] === '--strict') {
  process.argv.shift();
  strict = true;
}

const filename = process.argv[2];
if (!filename) {
  console.log(`Usage: ${argv1} <package-file>`);
  process.exit(1);
}

fs.readFile(filename, 'utf8', (err, data) => { // eslint-disable-line consistent-return
  if (err) {
    return console.log(`${argv1}: cannot read file '${filename}': ${err}`);
  }

  const json = JSON.parse(data);
  const stripes = json.stripes || {};
  const md = {
    id: `${json.name.replace(/^@/, '').replace('/', '_')}-${json.version}`,
    name: json.description,
    permissionSets: stripes.permissionSets || [],
  };
  if (strict) {
    const interfaces = stripes.okapiInterfaces || [];
    const optional = stripes.optionalOkapiInterfaces || [];
    md.requires = [].concat(
      Object.keys(interfaces).map(key => ({ id: key, version: interfaces[key] })),
      Object.keys(optional).map(key => ({ id: key, version: optional[key], optional: true })),
    );
  }

  console.log(JSON.stringify(md, undefined, 2));
});
<|endoftext|>


<commit_before>import JitsiMeetJS from '../lib-jitsi-meet';
import {
    CAMERA_FACING_MODE,
    MEDIA_TYPE
} from '../media';
import { getLocalParticipant } from '../participants';

import {
    TRACK_ADDED,
    TRACK_REMOVED,
    TRACK_UPDATED
} from './actionTypes';
import './middleware';
import './reducer';

const JitsiTrackErrors = JitsiMeetJS.errors.track;
const JitsiTrackEvents = JitsiMeetJS.events.track;

/**
 * Request to start capturing local audio and/or video. By default, the user
 * facing camera will be selected.
 *
 * @param {Object} [options] - For info @see JitsiMeetJS.createLocalTracks.
 * @returns {Function}
 */
export function createLocalTracks(options = {}) {
    return dispatch =>
        JitsiMeetJS.createLocalTracks({
            devices: options.devices || [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ],
            facingMode: options.facingMode || CAMERA_FACING_MODE.USER,
            cameraDeviceId: options.cameraDeviceId,
            micDeviceId: options.micDeviceId
        })
        .then(localTracks => dispatch(_updateLocalTracks(localTracks)))
        .catch(err => {
            console.error(
                `JitsiMeetJS.createLocalTracks.catch rejection reason: ${err}`);
        });
}

/**
 * Calls JitsiLocalTrack#dispose() on all local tracks ignoring errors when
 * track is already disposed. After that signals tracks to be removed.
 *
 * @returns {Function}
 */
export function destroyLocalTracks() {
    return (dispatch, getState) =>
        dispatch(
            _disposeAndRemoveTracks(
                getState()['features/base/tracks']
                    .filter(t => t.local)
                    .map(t => t.jitsiTrack)));
}

/**
 * Returns true if the provided JitsiTrack should be rendered as a mirror.
 *
 * We only want to show a video in mirrored mode when:
 * 1) The video source is local, and not remote.
 * 2) The video source is a camera, not a desktop (capture).
 * 3) The camera is capturing the user, not the environment.
 *
 * TODO Similar functionality is part of lib-jitsi-meet. This function should be
 * removed after https://github.com/jitsi/lib-jitsi-meet/pull/187 is merged.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @private
 * @returns {boolean}
 */
function _shouldMirror(track) {
    return (
        track
            && track.isLocal()
            && track.isVideoTrack()

            // XXX Type of the return value of
            // JitsiLocalTrack#getCameraFacingMode() happens to be named
            // CAMERA_FACING_MODE as well, it's defined by lib-jitsi-meet. Note
            // though that the type of the value on the right side of the
            // equality check is defined by jitsi-meet-react. The type
            // definitions are surely compatible today but that may not be the
            // case tomorrow.
            && track.getCameraFacingMode() === CAMERA_FACING_MODE.USER
            && !track.isScreenSharing()
    );
}

/**
 * Create an action for when a new track has been signaled to be added to the
 * conference.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_ADDED, track: Track }}
 */
export function trackAdded(track) {
    return (dispatch, getState) => {
        track.on(
            JitsiTrackEvents.TRACK_MUTE_CHANGED,
            () => dispatch(trackMutedChanged(track)));
        track.on(
            JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED,
            type => dispatch(trackVideoTypeChanged(track, type)));

        // participantId
        let participantId;

        if (track.isLocal()) {
            const participant = getLocalParticipant(getState);

            if (participant) {
                participantId = participant.id;
            }
        } else {
            participantId = track.getParticipantId();
        }

        return dispatch({
            type: TRACK_ADDED,
            track: {
                jitsiTrack: track,
                local: track.isLocal(),
                mediaType: track.getType(),
                mirrorVideo: _shouldMirror(track),
                muted: track.isMuted(),
                participantId,
                videoStarted: false,
                videoType: track.videoType
            }
        });
    };
}

/**
 * Create an action for when a track's muted state has been signaled to be
 * changed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackMutedChanged(track) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            muted: track.isMuted()
        }
    };
}

/**
 * Create an action for when a track has been signaled for removal from the
 * conference.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_REMOVED, track: Track }}
 */
export function trackRemoved(track) {
    return {
        type: TRACK_REMOVED,
        track: {
            jitsiTrack: track
        }
    };
}

/**
 * Signal that track's video started to play.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackVideoStarted(track) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            videoStarted: true
        }
    };
}

/**
 * Create an action for when participant video type changes.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @param {VIDEO_TYPE|undefined} videoType - Video type.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackVideoTypeChanged(track, videoType) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            videoType
        }
    };
}

/**
 * Signals passed tracks to be added.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} tracks - List of tracks.
 * @private
 * @returns {Function}
 */
function _addTracks(tracks) {
    return dispatch =>
        Promise.all(tracks.map(t => dispatch(trackAdded(t))));
}

/**
 * Disposes passed tracks and signals them to be removed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} tracks - List of tracks.
 * @private
 * @returns {Function}
 */
function _disposeAndRemoveTracks(tracks) {
    return dispatch =>
        Promise.all(
            tracks.map(t =>
                t.dispose()
                    .catch(err => {
                        // Track might be already disposed so ignore such an
                        // error. Of course, re-throw any other error(s).
                        if (err.name !== JitsiTrackErrors.TRACK_IS_DISPOSED) {
                            throw err;
                        }
                    })
            ))
            .then(Promise.all(tracks.map(t => dispatch(trackRemoved(t)))));
}

/**
 * Determines which local media tracks should be added, and which - removed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} currentTracks - List of
 * existing media tracks.
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} newTracks - List of new media
 * tracks.
 * @private
 * @returns {{
 *      tracksToAdd: JitsiLocalTrack[],
 *      tracksToRemove: JitsiLocalTrack[]
 * }}
 */
function _getLocalTracksToChange(currentTracks, newTracks) {
    const currentLocalAudio
        = currentTracks.find(t => t.isLocal() && t.isAudioTrack());
    const currentLocalVideo
        = currentTracks.find(t => t.isLocal() && t.isVideoTrack());
    const newLocalAudio = newTracks.find(t => t.isLocal() && t.isAudioTrack());
    const newLocalVideo = newTracks.find(t => t.isLocal() && t.isVideoTrack());
    const tracksToRemove = [];
    const tracksToAdd = [];

    if (newLocalAudio) {
        tracksToAdd.push(newLocalAudio);
        currentLocalAudio && tracksToRemove.push(newLocalVideo);
    }
    if (newLocalVideo) {
        tracksToAdd.push(newLocalVideo);
        currentLocalVideo && tracksToRemove.push(currentLocalVideo);
    }

    return {
        tracksToAdd,
        tracksToRemove
    };
}

/**
 * Set new local tracks replacing any existing tracks that were previously
 * available. Currently only one audio and one video local tracks are allowed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} [newTracks=[]] - List of new
 * media tracks.
 * @returns {Function}
 */
function _updateLocalTracks(newTracks = []) {
    return (dispatch, getState) => {
        const tracks
            = getState()['features/base/tracks'].map(t => t.jitsiTrack);
        const { tracksToAdd, tracksToRemove }
            = _getLocalTracksToChange(tracks, newTracks);

        return dispatch(_disposeAndRemoveTracks(tracksToRemove))
            .then(() => dispatch(_addTracks(tracksToAdd)));
    };
}
<commit_msg>fix tiny mistake on removing local tracks<commit_after>import JitsiMeetJS from '../lib-jitsi-meet';
import {
    CAMERA_FACING_MODE,
    MEDIA_TYPE
} from '../media';
import { getLocalParticipant } from '../participants';

import {
    TRACK_ADDED,
    TRACK_REMOVED,
    TRACK_UPDATED
} from './actionTypes';
import './middleware';
import './reducer';

const JitsiTrackErrors = JitsiMeetJS.errors.track;
const JitsiTrackEvents = JitsiMeetJS.events.track;

/**
 * Request to start capturing local audio and/or video. By default, the user
 * facing camera will be selected.
 *
 * @param {Object} [options] - For info @see JitsiMeetJS.createLocalTracks.
 * @returns {Function}
 */
export function createLocalTracks(options = {}) {
    return dispatch =>
        JitsiMeetJS.createLocalTracks({
            devices: options.devices || [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ],
            facingMode: options.facingMode || CAMERA_FACING_MODE.USER,
            cameraDeviceId: options.cameraDeviceId,
            micDeviceId: options.micDeviceId
        })
        .then(localTracks => dispatch(_updateLocalTracks(localTracks)))
        .catch(err => {
            console.error(
                `JitsiMeetJS.createLocalTracks.catch rejection reason: ${err}`);
        });
}

/**
 * Calls JitsiLocalTrack#dispose() on all local tracks ignoring errors when
 * track is already disposed. After that signals tracks to be removed.
 *
 * @returns {Function}
 */
export function destroyLocalTracks() {
    return (dispatch, getState) =>
        dispatch(
            _disposeAndRemoveTracks(
                getState()['features/base/tracks']
                    .filter(t => t.local)
                    .map(t => t.jitsiTrack)));
}

/**
 * Returns true if the provided JitsiTrack should be rendered as a mirror.
 *
 * We only want to show a video in mirrored mode when:
 * 1) The video source is local, and not remote.
 * 2) The video source is a camera, not a desktop (capture).
 * 3) The camera is capturing the user, not the environment.
 *
 * TODO Similar functionality is part of lib-jitsi-meet. This function should be
 * removed after https://github.com/jitsi/lib-jitsi-meet/pull/187 is merged.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @private
 * @returns {boolean}
 */
function _shouldMirror(track) {
    return (
        track
            && track.isLocal()
            && track.isVideoTrack()

            // XXX Type of the return value of
            // JitsiLocalTrack#getCameraFacingMode() happens to be named
            // CAMERA_FACING_MODE as well, it's defined by lib-jitsi-meet. Note
            // though that the type of the value on the right side of the
            // equality check is defined by jitsi-meet-react. The type
            // definitions are surely compatible today but that may not be the
            // case tomorrow.
            && track.getCameraFacingMode() === CAMERA_FACING_MODE.USER
            && !track.isScreenSharing()
    );
}

/**
 * Create an action for when a new track has been signaled to be added to the
 * conference.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_ADDED, track: Track }}
 */
export function trackAdded(track) {
    return (dispatch, getState) => {
        track.on(
            JitsiTrackEvents.TRACK_MUTE_CHANGED,
            () => dispatch(trackMutedChanged(track)));
        track.on(
            JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED,
            type => dispatch(trackVideoTypeChanged(track, type)));

        // participantId
        let participantId;

        if (track.isLocal()) {
            const participant = getLocalParticipant(getState);

            if (participant) {
                participantId = participant.id;
            }
        } else {
            participantId = track.getParticipantId();
        }

        return dispatch({
            type: TRACK_ADDED,
            track: {
                jitsiTrack: track,
                local: track.isLocal(),
                mediaType: track.getType(),
                mirrorVideo: _shouldMirror(track),
                muted: track.isMuted(),
                participantId,
                videoStarted: false,
                videoType: track.videoType
            }
        });
    };
}

/**
 * Create an action for when a track's muted state has been signaled to be
 * changed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackMutedChanged(track) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            muted: track.isMuted()
        }
    };
}

/**
 * Create an action for when a track has been signaled for removal from the
 * conference.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_REMOVED, track: Track }}
 */
export function trackRemoved(track) {
    return {
        type: TRACK_REMOVED,
        track: {
            jitsiTrack: track
        }
    };
}

/**
 * Signal that track's video started to play.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackVideoStarted(track) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            videoStarted: true
        }
    };
}

/**
 * Create an action for when participant video type changes.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)} track - JitsiTrack instance.
 * @param {VIDEO_TYPE|undefined} videoType - Video type.
 * @returns {{ type: TRACK_UPDATED, track: Track }}
 */
export function trackVideoTypeChanged(track, videoType) {
    return {
        type: TRACK_UPDATED,
        track: {
            jitsiTrack: track,
            videoType
        }
    };
}

/**
 * Signals passed tracks to be added.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} tracks - List of tracks.
 * @private
 * @returns {Function}
 */
function _addTracks(tracks) {
    return dispatch =>
        Promise.all(tracks.map(t => dispatch(trackAdded(t))));
}

/**
 * Disposes passed tracks and signals them to be removed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} tracks - List of tracks.
 * @private
 * @returns {Function}
 */
function _disposeAndRemoveTracks(tracks) {
    return dispatch =>
        Promise.all(
            tracks.map(t =>
                t.dispose()
                    .catch(err => {
                        // Track might be already disposed so ignore such an
                        // error. Of course, re-throw any other error(s).
                        if (err.name !== JitsiTrackErrors.TRACK_IS_DISPOSED) {
                            throw err;
                        }
                    })
            ))
            .then(Promise.all(tracks.map(t => dispatch(trackRemoved(t)))));
}

/**
 * Determines which local media tracks should be added, and which - removed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} currentTracks - List of
 * existing media tracks.
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} newTracks - List of new media
 * tracks.
 * @private
 * @returns {{
 *      tracksToAdd: JitsiLocalTrack[],
 *      tracksToRemove: JitsiLocalTrack[]
 * }}
 */
function _getLocalTracksToChange(currentTracks, newTracks) {
    const currentLocalAudio
        = currentTracks.find(t => t.isLocal() && t.isAudioTrack());
    const currentLocalVideo
        = currentTracks.find(t => t.isLocal() && t.isVideoTrack());
    const newLocalAudio = newTracks.find(t => t.isLocal() && t.isAudioTrack());
    const newLocalVideo = newTracks.find(t => t.isLocal() && t.isVideoTrack());
    const tracksToRemove = [];
    const tracksToAdd = [];

    if (newLocalAudio) {
        tracksToAdd.push(newLocalAudio);
        currentLocalAudio && tracksToRemove.push(currentLocalAudio);
    }
    if (newLocalVideo) {
        tracksToAdd.push(newLocalVideo);
        currentLocalVideo && tracksToRemove.push(currentLocalVideo);
    }

    return {
        tracksToAdd,
        tracksToRemove
    };
}

/**
 * Set new local tracks replacing any existing tracks that were previously
 * available. Currently only one audio and one video local tracks are allowed.
 *
 * @param {(JitsiLocalTrack|JitsiRemoteTrack)[]} [newTracks=[]] - List of new
 * media tracks.
 * @returns {Function}
 */
function _updateLocalTracks(newTracks = []) {
    return (dispatch, getState) => {
        const tracks
            = getState()['features/base/tracks'].map(t => t.jitsiTrack);
        const { tracksToAdd, tracksToRemove }
            = _getLocalTracksToChange(tracks, newTracks);

        return dispatch(_disposeAndRemoveTracks(tracksToRemove))
            .then(() => dispatch(_addTracks(tracksToAdd)));
    };
}
<|endoftext|>


<commit_before>Kwf.onJElementReady('.kwcMenuMobile', function mobileMenu(el, config) {
    var slideDuration = 400;
    var menuLink = el.children('.showMenu');
    var menu = null;
    var showMenuAfterLoad = false;
    var ajaxRequest = null;

    $(window).load(function(event) {
        showMenuAfterLoad = false;
        getMenu();
    });

    menuLink.click(function(event) {
        event.preventDefault();
        if (menu && menu.is(':animated')) return;

        var activeEl = $('.kwcMenuMobile').children('.showMenu.active');
        if (activeEl.length && activeEl.get(0) != menuLink.get(0)) {
            activeEl
                .removeClass('active')
                .next('.slider')
                .children('ul.menu')
                .slideToggle(slideDuration, function(){
                    $(this)
                        .parent().parent()
                        .removeClass('open');
                });
        }

        if (!menu) {
            showMenuAfterLoad = true;
            el.addClass('loading');
            getMenu();
        } else {
            menu.slideToggle(slideDuration);
        }
        menuLink.toggleClass('active');
        menuLink.parent().toggleClass('open');
    });

    var getMenu = function() {
        if (!ajaxRequest) {
            ajaxRequest = $.getJSON(config.controllerUrl + '/json-index', {
                subrootComponentId: config.subrootComponentId,
                componentId: config.componentId,
                kwfSessionToken: Kwf.sessionToken
            }, function(data) {
                var tpl = '
\n' +
                    '
\n' +
                        '{{#pages}}' +
                            '
\n' +
                                '{{name}}\n' +
                                '
\n' +
                                    '{{#children}}' +
                                        '{{> children}}\n' +
                                    '{{/children}}' +
                                '
\n' +
                            '
\n' +
                        '{{/pages}}' +
                    '
\n' +
                '
';
                var partials = {
                    children: '
\n' +
                        '{{name}}\n' +
                        '
\n' +
                            '{{#children}}' +
                                '{{> children}}\n' +
                            '{{/children}}' +
                        '
\n' +
                    '
\n'
                };
                el.append(Mustache.render(tpl, data, partials));
                menu = el.find('ul.menu');
                if (showMenuAfterLoad) menu.slideDown(slideDuration);

                menu.find('li.hasChildren ul.subMenu').prepend('
\n' +
                    '\n' +
                        trlKwf('back') + '\n' +
                    '\n' +
                '
');

                //after menu is loaded
                var currentLeft = 0;
                var left = 100;
                el.removeClass('loading');
                menu.find('li.hasChildren').each(function(index, child) {
                    $(child).children('a').click(function(event) {
                        menu.css('height', 'auto');
                        event.preventDefault();
                        currentLeft += left;
                        $(child).addClass('moved');
                        el.children('.slider').animate({
                            left: '-' + currentLeft + '%'
                        });
                        menu.animate({
                            height: $(child).find('ul.subMenu').height()
                        });
                    });
                });
                menu.find('li.back').each(function(index, child) {
                    $(child).children('a').click(function(event) {
                        menu.css('height', 'auto');
                        event.preventDefault();
                        currentLeft -= left;
                        el.children('.slider').animate({
                            left: '-' + currentLeft + '%'
                        }, function() {
                            $(child).parent().parent().removeClass('moved');
                        });
                        menu.animate({
                            height: $(child).parents('ul').parents('ul').height()
                        });
                    });
                });
            });
        }
    };
}, { checkVisibility: true, defer: true });
<commit_msg>Add function to hide menu if link is hash / anchor link<commit_after>Kwf.onJElementReady('.kwcMenuMobile', function mobileMenu(el, config) {
    var slideDuration = 400;
    var menuLink = el.children('.showMenu');
    var menu = null;
    var showMenuAfterLoad = false;
    var ajaxRequest = null;

    $(window).load(function(event) {
        showMenuAfterLoad = false;
        getMenu();
    });

    menuLink.click(function(event) {
        event.preventDefault();
        if (menu && menu.is(':animated')) return;

        var activeEl = $('.kwcMenuMobile').children('.showMenu.active');
        if (activeEl.length && activeEl.get(0) != menuLink.get(0)) {
            activeEl
                .removeClass('active')
                .next('.slider')
                .children('ul.menu')
                .slideToggle(slideDuration, function(){
                    $(this)
                        .parent().parent()
                        .removeClass('open');
                });
        }

        if (!menu) {
            showMenuAfterLoad = true;
            el.addClass('loading');
            getMenu();
        } else {
            menu.slideToggle(slideDuration);
        }
        menuLink.toggleClass('active');
        menuLink.parent().toggleClass('open');
    });

    var getMenu = function() {
        if (!ajaxRequest) {
            ajaxRequest = $.getJSON(config.controllerUrl + '/json-index', {
                subrootComponentId: config.subrootComponentId,
                componentId: config.componentId,
                kwfSessionToken: Kwf.sessionToken
            }, function(data) {
                var tpl = '
\n' +
                    '
\n' +
                        '{{#pages}}' +
                            '
\n' +
                                '{{name}}\n' +
                                '
\n' +
                                    '{{#children}}' +
                                        '{{> children}}\n' +
                                    '{{/children}}' +
                                '
\n' +
                            '
\n' +
                        '{{/pages}}' +
                    '
\n' +
                '
';
                var partials = {
                    children: '
\n' +
                        '{{name}}\n' +
                        '
\n' +
                            '{{#children}}' +
                                '{{> children}}\n' +
                            '{{/children}}' +
                        '
\n' +
                    '
\n'
                };
                el.append(Mustache.render(tpl, data, partials));
                menu = el.find('ul.menu');
                if (showMenuAfterLoad) menu.slideDown(slideDuration);

                menu.find('li.hasChildren ul.subMenu').prepend('
\n' +
                    '\n' +
                        trlKwf('back') + '\n' +
                    '\n' +
                '
');

                //after menu is loaded
                var currentLeft = 0;
                var left = 100;
                el.removeClass('loading');
                menu.find('li.hasChildren').each(function(index, child) {
                    $(child).children('a').click(function(event) {
                        menu.css('height', 'auto');
                        event.preventDefault();
                        currentLeft += left;
                        $(child).addClass('moved');
                        el.children('.slider').animate({
                            left: '-' + currentLeft + '%'
                        });
                        menu.animate({
                            height: $(child).find('ul.subMenu').height()
                        });
                    });
                });
                menu.find('li.back').each(function(index, child) {
                    $(child).children('a').click(function(event) {
                        menu.css('height', 'auto');
                        event.preventDefault();
                        currentLeft -= left;
                        el.children('.slider').animate({
                            left: '-' + currentLeft + '%'
                        }, function() {
                            $(child).parent().parent().removeClass('moved');
                        });
                        menu.animate({
                            height: $(child).parents('ul').parents('ul').height()
                        });
                    });
                });

                // Hide menu if link matches hash change (anchor scroll)
                menu.find('li > a').each(function(index, link) {
                    if($(link).attr('href').match('^/#')) {
                        $(link).click(function(e) {
                            menuLink.trigger('click');
                        });
                    }
                });
            });
        }
    };
}, { checkVisibility: true, defer: true });
<|endoftext|>


<commit_before>// Copyright 2014 Endless Mobile, Inc.

const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;

const Module = imports.app.interfaces.module;
const ImagePreviewer = imports.app.widgets.imagePreviewer;
const Utils = imports.app.utils;

/**
 * Class: AppBanner
 *
 * A module for the application's logo.
 *
 * CSS classes:
 *   app-banner - on the module itself
 *   subtitle - on the label displaying the app's subtitle
 */
const AppBanner = new Lang.Class({
    Name: 'AppBanner',
    GTypeName: 'EknAppBanner',
    Extends: Gtk.Grid,
    Implements: [ Module.Module ],

    Properties: {
        'factory': GObject.ParamSpec.override('factory', Module.Module),
        'factory-name': GObject.ParamSpec.override('factory-name', Module.Module),

        /**
         * Property: image-uri
         * A URI to the title image. Defaults to an empty string.
         */
        'image-uri': GObject.ParamSpec.string('image-uri', 'Page Title Image URI',
            'URI to the title image',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: subtitle
         * A subtitle for the application. Defaults to an empty string.
         */
        'subtitle': GObject.ParamSpec.string('subtitle', 'App subtitle',
            'A subtitle for the app',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: subtitle-capitalization
         * Manner in which the app's subtitle is formatted
         *
         * This property is a temporary stand-in for achieving this via the CSS
         * *text-transform* property.
         */
        'subtitle-capitalization': GObject.ParamSpec.enum('subtitle-capitalization',
            'Subtitle capitalization',
            'Manner in which the subtitle is formatted',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            EosKnowledgePrivate.TextTransformType,
            EosKnowledgePrivate.TextTransform.NONE),
    },

    // Note: The 50-px margin-start on the subtitle looks reasonable until we
    // get better instructions from design.
    Template: 'resource:///com/endlessm/knowledge/widgets/appBanner.ui',
    InternalChildren: [ 'subtitle-label' ],

    _init: function (props={}) {
        this.parent(props);

        this._logo = new ImagePreviewer.ImagePreviewer({
            visible: true,
        });
        this.attach(this._logo, 0, 0, 1, 1);

        if (this.image_uri) {
            let stream = Gio.File.new_for_uri(this.image_uri).read(null);
            this._logo.set_content(stream);
        }

        let subtitle = Utils.format_capitals(this.subtitle,
            this.subtitle_capitalization);
        // 758 = 0.74 px * 1024 Pango units / px
        // FIXME: Should be achievable through CSS when we fix GTK
        this._subtitle_label.label = ('' +
            GLib.markup_escape_text(subtitle, -1) + '');
        this._subtitle_label.visible = !!this.subtitle;
    },

    set subtitle(value) {
        if (this._subtitle === value)
            return;
        this._subtitle = value;
        this.notify('subtitle');
    },

    get subtitle() {
        return this._subtitle || '';
    },
});
<commit_msg>Fix m{in,ax}-fraction properties<commit_after>// Copyright 2014 Endless Mobile, Inc.

const EosKnowledgePrivate = imports.gi.EosKnowledgePrivate;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;

const Module = imports.app.interfaces.module;
const ImagePreviewer = imports.app.widgets.imagePreviewer;
const Utils = imports.app.utils;

/**
 * Class: AppBanner
 *
 * A module for the application's logo.
 *
 * CSS classes:
 *   app-banner - on the module itself
 *   subtitle - on the label displaying the app's subtitle
 */
const AppBanner = new Lang.Class({
    Name: 'AppBanner',
    GTypeName: 'EknAppBanner',
    Extends: Gtk.Grid,
    Implements: [ Module.Module ],

    Properties: {
        'factory': GObject.ParamSpec.override('factory', Module.Module),
        'factory-name': GObject.ParamSpec.override('factory-name', Module.Module),

        /**
         * Property: image-uri
         * A URI to the title image. Defaults to an empty string.
         */
        'image-uri': GObject.ParamSpec.string('image-uri', 'Page Title Image URI',
            'URI to the title image',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: subtitle
         * A subtitle for the application. Defaults to an empty string.
         */
        'subtitle': GObject.ParamSpec.string('subtitle', 'App subtitle',
            'A subtitle for the app',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: subtitle-capitalization
         * Manner in which the app's subtitle is formatted
         *
         * This property is a temporary stand-in for achieving this via the CSS
         * *text-transform* property.
         */
        'subtitle-capitalization': GObject.ParamSpec.enum('subtitle-capitalization',
            'Subtitle capitalization',
            'Manner in which the subtitle is formatted',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            EosKnowledgePrivate.TextTransformType,
            EosKnowledgePrivate.TextTransform.NONE),
        /**
         * Property: min-fraction
         * Delegates to <ImagePreviewer.min-fraction>
         *
         * Allows setting this property on the logo widget from the app.json.
         * It's construct only for simplicity.
         */
        'min-fraction': GObject.ParamSpec.float('min-fraction', 'Min fraction',
            'Min fraction of size to display the logo at',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            0.0, 1.0, 0.0),

        /**
         * Property: max-fraction
         * Delegates to <ImagePreviewer.max-fraction>
         *
         * Allows setting this property on the logo widget from the app.json.
         * It's construct only for simplicity.
         */
        'max-fraction': GObject.ParamSpec.float('max-fraction', 'Max fraction',
            'Max fraction of size to display the logo at',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            0.0, 1.0, 1.0),
    },

    // Note: The 50-px margin-start on the subtitle looks reasonable until we
    // get better instructions from design.
    Template: 'resource:///com/endlessm/knowledge/widgets/appBanner.ui',
    InternalChildren: [ 'subtitle-label' ],

    _init: function (props={}) {
        this.parent(props);

        this._logo = new ImagePreviewer.ImagePreviewer({
            visible: true,
            min_fraction: this.min_fraction,
            max_fraction: this.max_fraction,
        });
        this.attach(this._logo, 0, 0, 1, 1);

        if (this.image_uri) {
            let stream = Gio.File.new_for_uri(this.image_uri).read(null);
            this._logo.set_content(stream);
        }

        let subtitle = Utils.format_capitals(this.subtitle,
            this.subtitle_capitalization);
        // 758 = 0.74 px * 1024 Pango units / px
        // FIXME: Should be achievable through CSS when we fix GTK
        this._subtitle_label.label = ('' +
            GLib.markup_escape_text(subtitle, -1) + '');
        this._subtitle_label.visible = !!this.subtitle;
    },

    set subtitle(value) {
        if (this._subtitle === value)
            return;
        this._subtitle = value;
        this.notify('subtitle');
    },

    get subtitle() {
        return this._subtitle || '';
    },
});
<|endoftext|>


<commit_before>// Import analytics module
var analytics = require('analytics.js');

// Prepare shortcuts to raw time series and resampled store
var Raw = qm.store("Raw");
var Resampled = qm.store("Resampled");

// Initialize resampler from Raw to Resampled store. This results in
// in an equally spaced time series with 10 second interval.
Raw.addStreamAggr({ name: "Resample10second", type: "resampler",
    outStore: "Resampled", timestamp: "Time",
    fields: [ { name: "Value", interpolator: "previous" } ],
    createStore: false, interval: 10*1000 });
// Initialize stream aggregates on Resampled store for computing
// 1 minute and 10 minute exponential moving averages.
Resampled.addStreamAggr({ name: "tick", type: "timeSeriesTick",
    timestamp: "Time", value: "Value" });
Resampled.addStreamAggr({ name: "ema1m", type: "ema",
    inAggr: "tick", emaType: "previous", interval: 60*1000, initWindow: 10*1000 });
Resampled.addStreamAggr({ name: "ema10m", type: "ema",
    inAggr: "tick", emaType: "previous", interval: 600*1000, initWindow: 10*1000 });
// Add a chain of 5 EMA stream aggregates (itEma) and attach them to "tick"
Resampled.addStreamAggr({ type: "itEma",
    numIter: 5, tmInterval: 10000, initMinMSecs: 0, inAggr: "tick", prefix: "itEma10s"});
// Buffer for keeping track of the record from 1 minute ago (6 records
// behind, which equals 60 seconds since Resampled store is equally spaced
// with 10 second rate).
Resampled.addStreamAggr({ name: "delay", type: "recordBuffer", size: 6});

// Declare features from the resampled timeseries which we will use
// to train the recursive linear regression.
var ftrSpace = analytics.newFeatureSpace([
    { type: "numeric", source: "Resampled", field: "Value" },
    { type: "numeric", source: "Resampled", field: "Ema1" },
    { type: "numeric", source: "Resampled", field: "Ema2" },
    { type: "multinomial", source: "Resampled", field: "Time", datetime: true }
]);
console.log("Feature space has " + ftrSpace.dim + " dimensions");

// Initialize linear regression model.
var linreg = analytics.newRecLinReg({ "dim": ftrSpace.dim, "forgetFact": 1.0 });

// We register a trigger to Resampled store, which takes the latest record
// and updates the recursive linear regression model.
Resampled.addTrigger({
    onAdd: function (val) {
        // Get the latest value for EMAs and store them along the
        // record in the Resampled store.
        val.Ema1 = Resampled.getStreamAggr("ema1m").EMA;
        val.Ema2 = Resampled.getStreamAggr("ema10m").EMA;
        // See what would the current model would predict given
        // the new record, and store this for evaluation later on.
        val.Prediction = linreg.predict(ftrSpace.ftrVec(val))
        // Get the id of the record from a minute ago.
        var trainRecId = Resampled.getStreamAggr("delay").last;
        // Update the model, once we have at leats 1 minute worth of data
        if (trainRecId > 0) { linreg.learn(ftrSpace.ftrVec(Resampled[trainRecId]), val.Value); }
        // Get the current value and compare against prediction for a minute ago
        var diff = val.Value - Resampled[trainRecId].Prediction;
        console.log("Diff: " + diff + ", Value: " + val.Value + ", Prediction: " + Resampled[trainRecId].Prediction);
    }
});

// Load training data from CSV file.
var fin = fs.openRead("./sandbox/timeseries/series.csv");
var header = fin.readLine(); var lines = 0;
while (!fin.eof) {
    lines = lines + 1;
    if (lines % 1000 == 0) { console.log("Loaded: " + lines); }
    var line = fin.readLine();
    if (line == "") { continue; }
    try {
        var vals = line.split(',');
        var rec = { "Time": vals[1], "Value": parseFloat(vals[0]) };
        Raw.add(rec);
        //console.pause();
    } catch (err) {
        console.say("Raw", err);
    }
}

// Start console
console.say("Interactive mode: empty line to release");
console.start();
<commit_msg>Fixed spelling error<commit_after>// Import analytics module
var analytics = require('analytics.js');

// Prepare shortcuts to raw time series and resampled store
var Raw = qm.store("Raw");
var Resampled = qm.store("Resampled");

// Initialize resampler from Raw to Resampled store. This results
// in an equally spaced time series with 10 second interval.
Raw.addStreamAggr({ name: "Resample10second", type: "resampler",
    outStore: "Resampled", timestamp: "Time",
    fields: [ { name: "Value", interpolator: "previous" } ],
    createStore: false, interval: 10*1000 });
// Initialize stream aggregates on Resampled store for computing
// 1 minute and 10 minute exponential moving averages.
Resampled.addStreamAggr({ name: "tick", type: "timeSeriesTick",
    timestamp: "Time", value: "Value" });
Resampled.addStreamAggr({ name: "ema1m", type: "ema",
    inAggr: "tick", emaType: "previous", interval: 60*1000, initWindow: 10*1000 });
Resampled.addStreamAggr({ name: "ema10m", type: "ema",
    inAggr: "tick", emaType: "previous", interval: 600*1000, initWindow: 10*1000 });
// Add a chain of 5 EMA stream aggregates (itEma) and attach them to "tick"
Resampled.addStreamAggr({ type: "itEma",
    numIter: 5, tmInterval: 10000, initMinMSecs: 0, inAggr: "tick", prefix: "itEma10s"});
// Buffer for keeping track of the record from 1 minute ago (6 records
// behind, which equals 60 seconds since Resampled store is equally spaced
// with 10 second rate).
Resampled.addStreamAggr({ name: "delay", type: "recordBuffer", size: 6});

// Declare features from the resampled timeseries which we will use
// to train the recursive linear regression.
var ftrSpace = analytics.newFeatureSpace([
    { type: "numeric", source: "Resampled", field: "Value" },
    { type: "numeric", source: "Resampled", field: "Ema1" },
    { type: "numeric", source: "Resampled", field: "Ema2" },
    { type: "multinomial", source: "Resampled", field: "Time", datetime: true }
]);
console.log("Feature space has " + ftrSpace.dim + " dimensions");

// Initialize linear regression model.
var linreg = analytics.newRecLinReg({ "dim": ftrSpace.dim, "forgetFact": 1.0 });

// We register a trigger to Resampled store, which takes the latest record
// and updates the recursive linear regression model.
Resampled.addTrigger({
    onAdd: function (val) {
        // Get the latest value for EMAs and store them along the
        // record in the Resampled store.
        val.Ema1 = Resampled.getStreamAggr("ema1m").EMA;
        val.Ema2 = Resampled.getStreamAggr("ema10m").EMA;
        // See what the current model would predict given
        // the new record, and store this for evaluation later on.
        val.Prediction = linreg.predict(ftrSpace.ftrVec(val))
        // Get the id of the record from a minute ago.
        var trainRecId = Resampled.getStreamAggr("delay").last;
        // Update the model, once we have at leats 1 minute worth of data
        if (trainRecId > 0) { linreg.learn(ftrSpace.ftrVec(Resampled[trainRecId]), val.Value); }
        // Get the current value and compare against prediction for a minute ago
        var diff = val.Value - Resampled[trainRecId].Prediction;
        console.log("Diff: " + diff + ", Value: " + val.Value + ", Prediction: " + Resampled[trainRecId].Prediction);
    }
});

// Load training data from CSV file.
var fin = fs.openRead("./sandbox/timeseries/series.csv");
var header = fin.readLine(); var lines = 0;
while (!fin.eof) {
    lines = lines + 1;
    if (lines % 1000 == 0) { console.log("Loaded: " + lines); }
    var line = fin.readLine();
    if (line == "") { continue; }
    try {
        var vals = line.split(',');
        var rec = { "Time": vals[1], "Value": parseFloat(vals[0]) };
        Raw.add(rec);
        //console.pause();
    } catch (err) {
        console.say("Raw", err);
    }
}

// Start console
console.say("Interactive mode: empty line to release");
console.start();
<|endoftext|>


<commit_before><commit_msg>componentizd!<commit_after><|endoftext|>


<commit_before>import React, { PureComponent, PropTypes } from 'react'
import { connect } from 'react-redux'
import clearErrors from '../../actions/interface/clear-errors'

import closebutton from '../../assets/images/close.svg'

class ErrorComp extends PureComponent {
  static propTypes = {
    error: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).isRequired,
    clearErrors: PropTypes.func.isRequired
  }

  render() {
    const { error, clearErrors } = this.props
    if (!!error) {
      return (

{ error.type }

{ error.message }

      )
    } else {
      return null
    }
  }
}

const mapStateToProps = ({ error }) => ({ error })
export default connect(mapStateToProps, { clearErrors })(ErrorComp)
<commit_msg>Re-add Error<commit_after>import React, { PureComponent, PropTypes } from 'react'
import { connect } from 'react-redux'
import clearErrors from '../../actions/interface/clear-errors'

import { Modal, Button } from 'semantic-ui-react'

class ErrorComp extends PureComponent {
  static propTypes = {
    error: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).isRequired,
    clearErrors: PropTypes.func.isRequired
  }

  render() {
    const { error, clearErrors } = this.props
      return (
        <Modal size='small' open={!!error} onClose={clearErrors}>
          <Modal.Header>{ error.type }</Modal.Header>
          <Modal.Content>
{ error.message }
</Modal.Content>
          <Modal.Actions>
            <Button negative content='Close' onClick={clearErrors} />
          </Modal.Actions>
        </Modal>
      )
  }
}

const mapStateToProps = ({ error }) => ({ error })
export default connect(mapStateToProps, { clearErrors })(ErrorComp)
<|endoftext|>


<commit_before>var program = require('commander');
var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var dynamoDB = new AWS.DynamoDB();
var headers = [];

program.version('0.0.1').option('-t, --table [tablename]', 'Add the table you want to output to csv').option("-d, --describe").parse(process.argv);

if (!program.table) {
    console.log("You must specify a table");
    program.outputHelp();
    process.exit(1);
}

var query = {
    "TableName": program.table,
    "Limit": 1000,
};

var describeTable = function(query) {

    dynamoDB.describeTable({
        "TableName": program.table
    }, function(err, data) {

        if (!err) {

            console.dir(data.Table);

        } else console.dir(err);
    });
}

var scanDynamoDB = function(query) {

    dynamoDB.scan(query, function(err, data) {

        if (!err) {

            printout(data.Items) // Print out the subset of results.
            if (data.LastEvaluatedKey) { // Result is incomplete; there is more to come.
                query.ExclusiveStartKey = data.LastEvaluatedKey;
                scanDynamoDB(query);
            };
        } else console.dir(err);

    });
};

function arrayToCSV(array_input) {
    var string_output = "";
    for (var i = 0; i < array_input.length; i++) {
        array_input[i] = array_input[i].replace(/\r?\n/g, "");
        string_output += ('"' + array_input[i].replace(/\"/g, '\\"') + '"')
        if (i != array_input.length - 1) string_output += ","
    };
    return string_output;
}

function printout(items) {
    var headersMap = {};
    var values;
    var header;
    var value;

    if (headers.length == 0) {
        if (items.length > 0) {
            for (var i = 0; i < items.length; i++) {
                for (var key in items[i]) {
                    headersMap[key] = true;
                }
            }
        }
        for (var key in headersMap) {
            headers.push(key);
        }
        console.log(arrayToCSV(headers))
    }

    for (index in items) {
        values = [];
        for (i = 0; i < headers.length; i++) {
            value = "";
            header = headers[i];
            // Loop through the header rows, adding values if they exist
            if (items[index].hasOwnProperty(header)) {
                if (items[index][header].N) {
                    value = items[index][header].N;
                } else if (items[index][header].S) {
                    value = items[index][header].S;
                } else if (items[index][header].SS) {
                    value = items[index][header].SS.toString();
                } else if (items[index][header].B) {
                    value = items[index][header].B.toString('base64');
                }
            }
            values.push(value)
        }
        console.log(arrayToCSV(values))
    }
}

if (program.describe) describeTable(query);
else scanDynamoDB(query);
<commit_msg>add dynamo maps to the export<commit_after>var program = require('commander');
var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config.json');
var dynamoDB = new AWS.DynamoDB();
var headers = [];

program.version('0.0.1').option('-t, --table [tablename]', 'Add the table you want to output to csv').option("-d, --describe").parse(process.argv);

if (!program.table) {
    console.log("You must specify a table");
    program.outputHelp();
    process.exit(1);
}

var query = {
    "TableName": program.table,
    "Limit": 1000,
};

var describeTable = function(query) {

    dynamoDB.describeTable({
        "TableName": program.table
    }, function(err, data) {

        if (!err) {

            console.dir(data.Table);

        } else console.dir(err);
    });
}

var scanDynamoDB = function(query) {

    dynamoDB.scan(query, function(err, data) {

        if (!err) {

            printout(data.Items) // Print out the subset of results.
            if (data.LastEvaluatedKey) { // Result is incomplete; there is more to come.
                query.ExclusiveStartKey = data.LastEvaluatedKey;
                scanDynamoDB(query);
            };
        } else console.dir(err);

    });
};

function arrayToCSV(array_input) {
    var string_output = "";
    for (var i = 0; i < array_input.length; i++) {
        array_input[i] = array_input[i].replace(/\r?\n/g, "");
        string_output += ('"' + array_input[i].replace(/\"/g, '\\"') + '"')
        if (i != array_input.length - 1) string_output += ","
    };
    return string_output;
}

function printout(items) {
    var headersMap = {};
    var values;
    var header;
    var value;

    if (headers.length == 0) {
        if (items.length > 0) {
            for (var i = 0; i < items.length; i++) {
                for (var key in items[i]) {
                    headersMap[key] = true;
                }
            }
        }
        for (var key in headersMap) {
            headers.push(key);
        }
        console.log(arrayToCSV(headers))
    }

    for (index in items) {
        values = [];
        for (i = 0; i < headers.length; i++) {
            value = "";
            header = headers[i];
            // Loop through the header rows, adding values if they exist
            if (items[index].hasOwnProperty(header)) {
                if (items[index][header].N) {
                    value = items[index][header].N;
                } else if (items[index][header].S) {
                    value = items[index][header].S;
                } else if (items[index][header].SS) {
                    value = items[index][header].SS.toString();
                } else if (items[index][header].B) {
                    value = items[index][header].B.toString('base64');
                } else if (items[index][header].M) {
                    value = JSON.stringify(items[index][header].M);
                }
            }
            values.push(value)
        }
        console.log(arrayToCSV(values))
    }
}

if (program.describe) describeTable(query);
else scanDynamoDB(query);
<|endoftext|>