<commit_before>const TestRunner = require('test-runner')
const sort = require('../')
const a = require('assert')

const runner = new TestRunner()

runner.test('sortOrder: desc 1', function () {
  const fixture = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 }
  ]
  const expected = [
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 2, b: 2, c: 2 },
    { a: 2, b: 2, c: 3 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 1, c: 1 }
  ]
  const by = { a: 'asc', b: 'desc', c: 'asc' }
  const result = sort(fixture, by)
  a.deepStrictEqual(result, expected)
})

runner.test('sortOrder: desc 2', function () {
  const fixture = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 }
  ]
  const expected = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 3, b: 3, c: 3 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 1, b: 3, c: 4 },
  ]
  const by = { a: 'desc', b: 'asc', c: 'desc' }
  const result = sort(fixture, by)
  a.deepStrictEqual(result, expected)
})
<commit_msg>failing tests<commit_after>const TestRunner = require('test-runner')
const sort = require('../')
const a = require('assert')

const runner = new TestRunner()

runner.test('sortOrder: desc 1', function () {
  const fixture = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 }
  ]
  const expected = [
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 2, b: 2, c: 2 },
    { a: 2, b: 2, c: 3 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 1, c: 1 }
  ]
  const by = { a: 'asc', b: 'desc', c: 'asc' }
  const result = sort(fixture, by)
  a.deepStrictEqual(result, expected)
})

runner.test('sortOrder: desc 2', function () {
  const fixture = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 3, c: 4 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 3, b: 3, c: 3 },
    { a: 4, b: 3, c: 1 }
  ]
  const expected = [
    { a: 4, b: 1, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 4, b: 3, c: 1 },
    { a: 3, b: 3, c: 3 },
    { a: 2, b: 2, c: 3 },
    { a: 2, b: 2, c: 2 },
    { a: 1, b: 1, c: 4 },
    { a: 1, b: 2, c: 4 },
    { a: 1, b: 3, c: 4 },
  ]
  const by = { a: 'desc', b: 'asc', c: 'desc' }
  const result = sort(fixture, by)
  a.deepStrictEqual(result, expected)
})

runner.test('sortOrder: deep value', function () {
  const fixture = [
    { inner: { number: 2 } },
    { inner: { number: 3 } },
    { inner: { number: 5 } },
    { inner: { number: 1 } },
    { inner: { number: 4 } }
  ]
  const expected = [
    { inner: { number: 5 } },
    { inner: { number: 4 } },
    { inner: { number: 3 } },
    { inner: { number: 2 } },
    { inner: { number: 1 } }
  ]
  const by = { 'inner.number': 'desc' }
  const result = sort(fixture, by)
  a.deepStrictEqual(result, expected)
})
<|endoftext|>


<commit_before>import * as _ from 'lodash';
import { Jar } from 'jvm';

import { Hook } from './analysis/Hook';
import { Context } from './analysis/Context';

let patchClasses = (jar) => {
  for (let [name, cls] of jar) {
    cls.fieldTypes = () => {
      return _.unique(_.pluck(cls.fields, 'desc')).length;
    };
    cls.fieldCount = (desc) => {
      return cls.fields.filter(f => f.desc === desc).length;
    };
    cls.findField = (desc) => {
      return _.find(cls.fields, (f) => f.desc === desc);
    }
  }
};

let buildHooks = (ctx) => {
  let hooks = _.map(require('../hooks'), (def, name) => new Hook(ctx, name, def));
  return _.sortBy(hooks, (hook) => hook.dependsOn.length);
}

Jar.unpack(process.argv[2])
  .then((jar) => {
    patchClasses(jar);

    let ctx = new Context(jar);
    let hooks = buildHooks(ctx);

    ctx.log.record(() => {
      _.each(hooks, (hook) => {
        if ( ! hook.canRun()) {
          console.log(':(', hook.name)
          return;
        }

        for (let [name, cls] of jar) {
          if (hook.run(cls)) {
            break;
          }
        }
      });
    });

    return ctx;
  })
  .then((ctx) => {
    ctx.log.print();
  })
  .catch(console.error.bind(console));
<commit_msg>promisify class patching<commit_after>import * as _ from 'lodash';
import { Jar } from 'jvm';

import { Hook } from './analysis/Hook';
import { Context } from './analysis/Context';

let patchClasses = (jar) => {
  for (let [name, cls] of jar) {
    cls.fieldTypes = () => {
      return _.unique(_.pluck(cls.fields, 'desc')).length;
    };
    cls.fieldCount = (desc) => {
      return cls.fields.filter(f => f.desc === desc).length;
    };
    cls.findField = (desc) => {
      return _.find(cls.fields, (f) => f.desc === desc);
    }
  }

  return jar;
};

let buildHooks = (ctx) => {
  let hooks = _.map(require('../hooks'), (def, name) => new Hook(ctx, name, def));
  return _.sortBy(hooks, (hook) => hook.dependsOn.length);
}

Jar.unpack(process.argv[2])
  .then(patchClasses)
  .then((jar) => {
    let ctx = new Context(jar);
    let hooks = buildHooks(ctx);

    ctx.log.record(() => {
      _.each(hooks, (hook) => {
        if ( ! hook.canRun()) {
          console.log(':(', hook.name)
          return;
        }

        for (let [name, cls] of jar) {
          if (hook.run(cls)) {
            break;
          }
        }
      });
    });

    return ctx;
  })
  .then((ctx) => {
    ctx.log.print();
  })
  .catch(console.error.bind(console));
<|endoftext|>


<commit_before>'use strict';

var mongoDBStoreCachedFactory = require('../../lib/index.js');

var express = require('express');
var session = require('express-session');
var MongoDBStoreCached = mongoDBStoreCachedFactory(session);
var request = require('request');

var sinon = require('sinon');

describe('MongoDBStoreCached', function () {

    var server, store,
        getMethod, destroyMethod, setMethod,
        cacheGetMethod, cacheRemoveMethod, cacheSetMethod;

    before(function (done) {

        store = new MongoDBStoreCached({
            collection: 'connect-mongodb-session-cached'
        });

        getMethod = sinon.spy(store, 'get');
        destroyMethod = sinon.spy(store, 'destroy');
        setMethod = sinon.spy(store, 'set');

        cacheGetMethod = sinon.spy(store._cache, 'get');
        cacheRemoveMethod = sinon.spy(store._cache, 'remove');
        cacheSetMethod = sinon.spy(store._cache, 'set');

        request = request.defaults({jar: true});

        var app = express();

        app.use(session({
            store: store,
            secret: 'sssh!',
            saveUninitialized: true,
            resave: true,
            unset: 'destroy'
        }));

        app.get('/destroy', function (req, res) {
            delete req.session;
            res.send('Destroyed!');
        });

        app.get('*', function (req, res) {
            res.send('Hello World!');
        });

        server = app.listen(3030, function () {
            done();
        });

    });

    after(function (done) {

        server.close();
        store.db.close();
        store._cache.destroy();
        done();

    });

    it('should set the session entry', function (done) {

        request('http://localhost:3030', function (err, response, body) {

            expect(body).to.eql('Hello World!');

            expect(getMethod.callCount).to.eql(0);
            expect(destroyMethod.callCount).to.eql(0);
            expect(setMethod.callCount).to.eql(2);

            expect(cacheGetMethod.callCount).to.eql(0);
            expect(cacheRemoveMethod.callCount).to.eql(0);
            expect(cacheSetMethod.callCount).to.eql(2);

            done();

        });

    });

    it('should get the session from cache', function (done) {

        request('http://localhost:3030', function (err, response, body) {

            expect(body).to.eql('Hello World!');

            expect(getMethod.callCount).to.eql(1);
            expect(destroyMethod.callCount).to.eql(0);
            expect(setMethod.callCount).to.eql(3);

            expect(cacheGetMethod.callCount).to.eql(1);
            expect(cacheRemoveMethod.callCount).to.eql(0);
            expect(cacheSetMethod.callCount).to.eql(3);

            done();

        });

    });

    it('should get the session from db if cache empty', function (done) {

        store._cache.remove(cacheSetMethod.lastCall.args[0]);

        request('http://localhost:3030', function (err, response, body) {

            expect(body).to.eql('Hello World!');

            expect(getMethod.callCount).to.eql(2);
            expect(destroyMethod.callCount).to.eql(0);
            expect(setMethod.callCount).to.eql(4);

            expect(cacheGetMethod.callCount).to.eql(2);
            expect(cacheRemoveMethod.callCount).to.eql(1);
            expect(cacheSetMethod.callCount).to.eql(4);

            expect(cacheGetMethod.threw('Error')).to.eql(true);

            done();

        });

    });

    it('should destroy the session entry', function (done) {

        request('http://localhost:3030/destroy', function (err, response, body) {

            expect(body).to.eql('Destroyed!');

            expect(getMethod.callCount).to.eql(3);
            expect(destroyMethod.callCount).to.eql(1);
            expect(setMethod.callCount).to.eql(4);

            expect(cacheGetMethod.callCount).to.eql(3);
            expect(cacheRemoveMethod.callCount).to.eql(2);
            expect(cacheSetMethod.callCount).to.eql(4);

            done();

        });

    });

});
<commit_msg>More tests<commit_after>'use strict';

var mongoDBStoreCachedFactory = require('../../lib/index.js');

var express = require('express');
var session = require('express-session');
var MongoDBStoreCached = mongoDBStoreCachedFactory(session);
var request = require('request');

var sinon = require('sinon');

describe('MongoDBStoreCached', function () {

    var server, store,
        getMethod, destroyMethod, setMethod,
        cacheGetMethod, cacheRemoveMethod, cacheSetMethod;

    describe('with default options', function () {

        before(function (done) {

            store = new MongoDBStoreCached({
                collection: 'connect-mongodb-session-cached'
            });

            getMethod = sinon.spy(store, 'get');
            destroyMethod = sinon.spy(store, 'destroy');
            setMethod = sinon.spy(store, 'set');

            cacheGetMethod = sinon.spy(store._cache, 'get');
            cacheRemoveMethod = sinon.spy(store._cache, 'remove');
            cacheSetMethod = sinon.spy(store._cache, 'set');

            request = request.defaults({ jar: request.jar() });

            var app = express();

            app.use(session({
                store: store,
                secret: 'sssh!',
                saveUninitialized: true,
                resave: true,
                unset: 'destroy'
            }));

            app.get('/destroy', function (req, res) {
                delete req.session;
                res.send('Destroyed!');
            });

            app.get('*', function (req, res) {
                res.send('Hello World!');
            });

            server = app.listen(3030, function () {
                done();
            });

        });

        after(function (done) {

            server.close();
            store.db.close();
            store._cache.destroy();
            done();

        });

        it('should set the session entry', function (done) {

            request('http://localhost:3030', function (err, response, body) {

                expect(body).to.eql('Hello World!');

                expect(getMethod.callCount).to.eql(0);
                expect(destroyMethod.callCount).to.eql(0);
                expect(setMethod.callCount).to.eql(2);

                expect(cacheGetMethod.callCount).to.eql(0);
                expect(cacheRemoveMethod.callCount).to.eql(0);
                expect(cacheSetMethod.callCount).to.eql(2);

                done();

            });

        });

        it('should get the session from cache', function (done) {

            request('http://localhost:3030', function (err, response, body) {

                expect(body).to.eql('Hello World!');

                expect(getMethod.callCount).to.eql(1);
                expect(destroyMethod.callCount).to.eql(0);
                expect(setMethod.callCount).to.eql(3);

                expect(cacheGetMethod.callCount).to.eql(1);
                expect(cacheRemoveMethod.callCount).to.eql(0);
                expect(cacheSetMethod.callCount).to.eql(3);

                done();

            });

        });

        it('should get the session from db if cache empty', function (done) {

            store._cache.remove(cacheSetMethod.lastCall.args[0]);

            request('http://localhost:3030', function (err, response, body) {

                expect(body).to.eql('Hello World!');

                expect(getMethod.callCount).to.eql(2);
                expect(destroyMethod.callCount).to.eql(0);
                expect(setMethod.callCount).to.eql(4);

                expect(cacheGetMethod.callCount).to.eql(2);
                expect(cacheRemoveMethod.callCount).to.eql(1);
                expect(cacheSetMethod.callCount).to.eql(4);

                expect(cacheGetMethod.threw('Error')).to.eql(true);

                done();

            });

        });

        it('should destroy the session entry', function (done) {

            request('http://localhost:3030/destroy', function (err, response, body) {

                expect(body).to.eql('Destroyed!');

                expect(getMethod.callCount).to.eql(3);
                expect(destroyMethod.callCount).to.eql(1);
                expect(setMethod.callCount).to.eql(4);

                expect(cacheGetMethod.callCount).to.eql(3);
                expect(cacheRemoveMethod.callCount).to.eql(2);
                expect(cacheSetMethod.callCount).to.eql(4);

                done();

            });

        });

    });

    describe('with option for short cache expiry', function () {

        before(function (done) {

            store = new MongoDBStoreCached({
                collection: 'connect-mongodb-session-cached',
                expireCacheAfter: 10
            });

            getMethod = sinon.spy(store, 'get');
            destroyMethod = sinon.spy(store, 'destroy');
            setMethod = sinon.spy(store, 'set');

            cacheGetMethod = sinon.spy(store._cache, 'get');
            cacheRemoveMethod = sinon.spy(store._cache, 'remove');
            cacheSetMethod = sinon.spy(store._cache, 'set');

            request = request.defaults({ jar: request.jar() });

            var app = express();

            app.use(session({
                store: store,
                secret: 'sssh!',
                saveUninitialized: true,
                resave: true,
                unset: 'destroy'
            }));

            app.get('/destroy', function (req, res) {
                delete req.session;
                res.send('Destroyed!');
            });

            app.get('*', function (req, res) {
                res.send('Hello World!');
            });

            server = app.listen(3030, function () {
                done();
            });

        });

        after(function (done) {

            server.close();
            store.db.close();
            store._cache.destroy();
            done();

        });

        it('should load the session from db after cache expired', function (done) {

            request('http://localhost:3030', function (err, response, body) {

                expect(body).to.eql('Hello World!');

                expect(getMethod.callCount).to.eql(0);
                expect(destroyMethod.callCount).to.eql(0);
                expect(setMethod.callCount).to.eql(2);

                expect(cacheGetMethod.callCount).to.eql(0);
                expect(cacheRemoveMethod.callCount).to.eql(0);
                expect(cacheSetMethod.callCount).to.eql(2);

                setTimeout(function () {

                    request('http://localhost:3030', function (err, response, body) {

                        expect(body).to.eql('Hello World!');

                        expect(getMethod.callCount).to.eql(1);
                        expect(destroyMethod.callCount).to.eql(0);
                        expect(setMethod.callCount).to.eql(3);

                        expect(cacheGetMethod.callCount).to.eql(1);
                        expect(cacheRemoveMethod.callCount).to.eql(0);
                        expect(cacheSetMethod.callCount).to.eql(3);

                        expect(cacheGetMethod.threw('Error')).to.eql(true);

                        done();

                    });

                }, 20);

            });

        });

    });

});
<|endoftext|>


<commit_before>var test = require('tinytap');

test('string formatting', function (t) {
  // basic checks
  var fmt = require('util').format;
  t.ok(fmt, "format function available")
  t.equal(fmt("%s, %s!", "Hello", "world"), "Hello, world!");

  // examples from http://nodejs.org/api/util.html#util_util_format_format
  t.equal(fmt('%s:%s', 'foo'), 'foo:%s');
  t.equal(fmt('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz');
  t.equal(fmt('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz');
  t.equal(fmt(1, 2, 3), '1 2 3');

  // more mismatched format string cases
  t.equal(fmt("%s %x %s", "foo", "bar", "baz"), "foo %x bar baz");
  t.equal(fmt("%%%"), "%%");

  // stringification and inspect behaviour
  t.equal(fmt("%s", "a"), "a");
  t.equal(fmt("%s", true), "true");     // NOTE: fails due to https://github.com/tessel/runtime/issues/292
  t.equal(fmt("%s", null), "null");     // NOTE: fails due to https://github.com/tessel/runtime/issues/294
  t.equal(fmt("%s", void 0), "undefined");
  t.equal(fmt("%s", /abcdef/g), "/abcdef/g");   // FAILS: see https://github.com/tessel/runtime/issues/295
  var o = {inspect:function () { return 42; }};
  t.equal(fmt("%s", o), "[object Object]");
  t.equal(fmt("", o), " 42");

  // number tests
  t.equal(fmt("%d", new Date(0x42)), "66");     // FAILS: see https://github.com/tessel/runtime/issues/296
  t.equal(fmt("%d", "0xFF"), "255");
  t.equal(fmt("%d", "010"), "10");
  t.equal(fmt("%d", false), "0");
  t.equal(fmt("%d", "x"), "NaN");               // FAILS: see https://github.com/tessel/runtime/issues/298

  // sanity check json
  t.equal(fmt("%j%j %j%j%j", true, false, null, '', void 0), "truefalse null\"\"undefined");
  t.equal(fmt("%j", {foo:42,bar:void 0}), "{\"foo\":42}");
  t.equal(fmt("%j", new Date(0x42)), "\"1970-01-01T00:00:00.066Z\""); // FAILS: https://github.com/tessel/runtime/issues/299

  t.end();
});

test('object inspection', function (t) {
  // basic checks
  var fmt = require('util').inspect;
  t.ok(fmt, "inspect function available")
  t.equal(fmt({}).replace(/\s/g), "{}");

  // TODO: convert this manually-verified sample to actual tests…
  // (left because it at least verifies no crash/hang)
  var ref = {};
  ref.ref = ref;
  fmt({
    a: {
      b: {c:3,d:[1,2,3],fn:fmt},
      2: 1
    },
    z: [
      {inspect:function () { return "VALUE"; }},
      function fn() { return ref; },
      Buffer([1,2,3]),
      new Date(),
      /abc/g,
      true,
      null,
      ref
    ]
  });

  t.end();
});

test('circular inspection', function (t) {
  var fmt = require('util').inspect;

  var o = {n:42};
  t.equal(fmt({foo:o, bar:o}).match(/.*Circular.*/), null);

  o.o = o;
  t.equal(fmt(o).match(/Circular/g).length, 1);
  t.equal(fmt({foo:o, bar:o}).match(/Circular/g).length, 2);
});
<commit_msg>update util format test failure issue notes<commit_after>var test = require('tinytap');

test('string formatting', function (t) {
  // basic checks
  var fmt = require('util').format;
  t.ok(fmt, "format function available")
  t.equal(fmt("%s, %s!", "Hello", "world"), "Hello, world!");

  // examples from http://nodejs.org/api/util.html#util_util_format_format
  t.equal(fmt('%s:%s', 'foo'), 'foo:%s');
  t.equal(fmt('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz');
  t.equal(fmt('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz');
  t.equal(fmt(1, 2, 3), '1 2 3');

  // more mismatched format string cases
  t.equal(fmt("%s %x %s", "foo", "bar", "baz"), "foo %x bar baz");
  t.equal(fmt("%%%"), "%%");

  // stringification and inspect behaviour
  t.equal(fmt("%s", "a"), "a");
  t.equal(fmt("%s", true), "true");
  t.equal(fmt("%s", null), "null");     // NOTE: fails due to https://github.com/tessel/runtime/issues/294
  t.equal(fmt("%s", void 0), "undefined");
  t.equal(fmt("%s", /abcdef/g), "/abcdef/g");   // FAILS: see https://github.com/tessel/runtime/issues/450
  var o = {inspect:function () { return 42; }};
  t.equal(fmt("%s", o), "[object Object]");     // FAILS: see https://github.com/tessel/runtime/issues/450
  t.equal(fmt("", o), " 42");

  // number tests
  t.equal(fmt("%d", new Date(0x42)), "66");
  t.equal(fmt("%d", "0xFF"), "255");
  t.equal(fmt("%d", "010"), "10");
  t.equal(fmt("%d", false), "0");
  t.equal(fmt("%d", "x"), "NaN");

  // sanity check json
  t.equal(fmt("%j%j %j%j%j", true, false, null, '', void 0), "truefalse null\"\"undefined");
  t.equal(fmt("%j", {foo:42,bar:void 0}), "{\"foo\":42}");
  t.equal(fmt("%j", new Date(0x42)), "\"1970-01-01T00:00:00.066Z\""); // FAILS: https://github.com/tessel/runtime/issues/299

  t.end();
});

test('object inspection', function (t) {
  // basic checks
  var fmt = require('util').inspect;
  t.ok(fmt, "inspect function available")
  t.equal(fmt({}).replace(/\s/g), "{}");

  // TODO: convert this manually-verified sample to actual tests…
  // (left because it at least verifies no crash/hang)
  var ref = {};
  ref.ref = ref;
  fmt({
    a: {
      b: {c:3,d:[1,2,3],fn:fmt},
      2: 1
    },
    z: [
      {inspect:function () { return "VALUE"; }},
      function fn() { return ref; },
      Buffer([1,2,3]),
      new Date(),
      /abc/g,
      true,
      null,
      ref
    ]
  });

  t.end();
});

test('circular inspection', function (t) {
  var fmt = require('util').inspect;

  var o = {n:42};
  t.equal(fmt({foo:o, bar:o}).match(/.*Circular.*/), null);

  o.o = o;
  t.equal(fmt(o).match(/Circular/g).length, 1);
  t.equal(fmt({foo:o, bar:o}).match(/Circular/g).length, 2);
});
<|endoftext|>


<commit_before>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import 'babel/polyfill';
import React from 'react/addons';
import BrowserHistory from 'react-router/lib/BrowserHistory';
import Root from './components/Root';
import FastClick from 'fastclick';
// import App from './components/App';
// import Dispatcher from './core/Dispatcher';
// import AppActions from './actions/AppActions';
// import ActionTypes from './constants/ActionTypes';

// let path = decodeURI(window.location.pathname);
// let onSetMeta = (name, content) => {
//   // Remove and create a new <meta /> tag in order to make it work
//   // with bookmarks in Safari
//   let elements = document.getElementsByTagName('meta');
//   [].slice.call(elements).forEach((element) => {
//     if (element.getAttribute('name') === name) {
//       element.parentNode.removeChild(element);
//     }
//   });
//   let meta = document.createElement('meta');
//   meta.setAttribute('name', name);
//   meta.setAttribute('content', content);
//   document.getElementsByTagName('head')[0].appendChild(meta);
// };

function run() {
  // Render the top-level React component

  const rootElement = document.getElementById('root');
  const history = new BrowserHistory();

  React.render(<Root history={history}/>, rootElement);

  // let props = {
  //   path: path,
  //   context: {
  //     onSetTitle: value => document.title = value,
  //     onSetMeta
  //   }
  // };
  // let element = React.createElement(App, props);
  // React.render(element, document.getElementById('app'), () => {
  //   let css = document.getElementById('css');
  //   css.parentNode.removeChild(css);
  // });

  // // Update `Application.path` prop when `window.location` is changed
  // Dispatcher.register((action) => {
  //   if (action.type === ActionTypes.CHANGE_LOCATION) {
  //     element = React.cloneElement(element, {path: action.path});
  //     React.render(element, document.getElementById('app'));
  //   }
  // });
}

// Run the application when both DOM is ready
// and page content is loaded
Promise.all([
  new Promise((resolve) => {
    if (window.addEventListener) {
      window.addEventListener('DOMContentLoaded', resolve);
    } else {
      window.attachEvent('onload', resolve);
    }
  }).then(() => FastClick.attach(document.body))// ,
  // new Promise((resolve) => AppActions.loadPage(path, resolve))
]).then(run);
<commit_msg>Disable FastClick.js<commit_after>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import 'babel/polyfill';
import React from 'react/addons';
import BrowserHistory from 'react-router/lib/BrowserHistory';
import Root from './components/Root';
// import FastClick from 'fastclick';
// import App from './components/App';
// import Dispatcher from './core/Dispatcher';
// import AppActions from './actions/AppActions';
// import ActionTypes from './constants/ActionTypes';

// let path = decodeURI(window.location.pathname);
// let onSetMeta = (name, content) => {
//   // Remove and create a new <meta /> tag in order to make it work
//   // with bookmarks in Safari
//   let elements = document.getElementsByTagName('meta');
//   [].slice.call(elements).forEach((element) => {
//     if (element.getAttribute('name') === name) {
//       element.parentNode.removeChild(element);
//     }
//   });
//   let meta = document.createElement('meta');
//   meta.setAttribute('name', name);
//   meta.setAttribute('content', content);
//   document.getElementsByTagName('head')[0].appendChild(meta);
// };

function run() {
  // Render the top-level React component

  const rootElement = document.getElementById('root');
  const history = new BrowserHistory();

  React.render(<Root history={history}/>, rootElement);

  // let props = {
  //   path: path,
  //   context: {
  //     onSetTitle: value => document.title = value,
  //     onSetMeta
  //   }
  // };
  // let element = React.createElement(App, props);
  // React.render(element, document.getElementById('app'), () => {
  //   let css = document.getElementById('css');
  //   css.parentNode.removeChild(css);
  // });

  // // Update `Application.path` prop when `window.location` is changed
  // Dispatcher.register((action) => {
  //   if (action.type === ActionTypes.CHANGE_LOCATION) {
  //     element = React.cloneElement(element, {path: action.path});
  //     React.render(element, document.getElementById('app'));
  //   }
  // });
}

// Run the application when both DOM is ready
// and page content is loaded
Promise.all([
  new Promise((resolve) => {
    if (window.addEventListener) {
      window.addEventListener('DOMContentLoaded', resolve);
    } else {
      window.attachEvent('onload', resolve);
    }
  }).then(/* () => FastClick.attach(document.body)*/ )// ,
  // new Promise((resolve) => AppActions.loadPage(path, resolve))
]).then(run);
<|endoftext|>


<commit_before>var SVG_NS = "http://www.w3.org/2000/svg"

export default function (app) {
  var view = app.view || function () {
    return ""
  }

  var model
  var actions = {}
  var subscriptions = []
  var hooks = {
    onError: [],
    onAction: [],
    onUpdate: [],
    onRender: []
  }

  var node
  var root
  var batch = []
  var plugins = app.plugins || []

  for (var i = -1; i < plugins.length; i++) {
    var plugin = i < 0 ? app : plugins[i](app)

    if (plugin.model !== undefined) {
      model = merge(model, plugin.model)
    }

    if (plugin.actions) {
      init(actions, plugin.actions)
    }

    if (plugin.subscriptions) {
      subscriptions = subscriptions.concat(plugin.subscriptions)
    }

    var _hooks = plugin.hooks
    if (_hooks) {
      Object.keys(_hooks).forEach(function (key) {
        hooks[key].push(_hooks[key])
      })
    }
  }

  function onError(error) {
    for (var i = 0; i < hooks.onError.length; i++) {
      hooks.onError[i](error)
    }

    if (i <= 0) {
      throw error
    }
  }

  function init(container, group, lastName) {
    Object.keys(group).forEach(function (key) {
      if (!container[key]) {
        container[key] = {}
      }

      var name = lastName ? lastName + "." + key : key
      var action = group[key]
      var i

      if (typeof action === "function") {
        container[key] = function (data) {
          for (i = 0; i < hooks.onAction.length; i++) {
            hooks.onAction[i](name, data)
          }

          var result = action(model, data, actions, onError)

          if (result == null || typeof result.then === "function") {
            return result

          } else {
            for (i = 0; i < hooks.onUpdate.length; i++) {
              hooks.onUpdate[i](model, result, data)
            }

            model = merge(model, result)
            render(model, view)
          }
        }
      } else {
        init(container[key], action, name)
      }
    })
  }

  load(function () {
    root = app.root || document.body.appendChild(document.createElement("div"))

    render(model, view)

    for (var i = 0; i < subscriptions.length; i++) {
      subscriptions[i](model, actions, onError)
    }
  })

  function load(fn) {
    if (document.readyState[0] !== "l") {
      fn()
    } else {
      document.addEventListener("DOMContentLoaded", fn)
    }
  }

  function render(model, view) {
    for (i = 0; i < hooks.onRender.length; i++) {
      view = hooks.onRender[i](model, view)
    }

    patch(root, node, node = view(model, actions), 0)

    for (var i = 0; i < batch.length; i++) {
      batch[i]()
    }

    batch = []
  }

  function merge(a, b) {
    var obj = {}
    var key

    if (isPrimitive(b) || Array.isArray(b)) {
      return b
    }

    for (key in a) {
      obj[key] = a[key]
    }
    for (key in b) {
      obj[key] = b[key]
    }

    return obj
  }

  function isPrimitive(type) {
    type = typeof type
    return type === "string" || type === "number" || type === "boolean"
  }

  function defer(fn, data) {
    setTimeout(function () {
      fn(data)
    }, 0)
  }

  function shouldUpdate(a, b) {
    return a.tag !== b.tag || typeof a !== typeof b || isPrimitive(a) && a !== b
  }

  function createElementFrom(node, isSVG) {
    var element

    if (typeof node === "string") {
      element = document.createTextNode(node)

    } else {
      element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS(SVG_NS, node.tag)
        : document.createElement(node.tag)

      for (var name in node.data) {
        if (name === "onCreate") {
          defer(node.data[name], element)
        } else {
          setElementData(element, name, node.data[name])
        }
      }

      for (var i = 0; i < node.children.length; i++) {
        element.appendChild(createElementFrom(node.children[i], isSVG))
      }
    }

    return element
  }

  function removeElementData(element, name, value) {
    element[name] = value
    element.removeAttribute(name)
  }

  function setElementData(element, name, value, oldValue) {
    name = name.toLowerCase()

    if (!value) {
      removeElementData(element, name, value, oldValue)

    } else if (name === "style") {
      for (var i in oldValue) {
        if (!(i in value)) {
          element.style[i] = ""
        }
      }

      for (var i in value) {
        element.style[i] = value[i]
      }
    } else {
      element.setAttribute(name, value)

      if (element.namespaceURI !== SVG_NS) {
        if (element.type === "text") {
          var oldSelStart = element.selectionStart
          var oldSelEnd = element.selectionEnd
        }

        element[name] = value

        if (oldSelStart >= 0) {
          element.setSelectionRange(oldSelStart, oldSelEnd)
        }
      }
    }
  }

  function updateElementData(element, data, oldData) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = oldData[name]
      var realValue = element[name]

      if (name === "onUpdate") {
        defer(value, element)

      } else if (
        value !== oldValue || typeof realValue === "boolean" && realValue !== value
      ) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function patch(parent, oldNode, node, index) {
    var element = parent.childNodes[index]

    if (oldNode === undefined) {
      parent.appendChild(createElementFrom(node))

    } else if (node === undefined) {
      // Removing a child one at a time updates the DOM, so we end up
      // with an index out of date that needs to be adjusted. Instead,
      // collect all the elements and delete them in a batch.

      batch.push(parent.removeChild.bind(parent, element))

      if (oldNode && oldNode.data && oldNode.data.onRemove) {
        defer(oldNode.data.onRemove, element)
      }

    } else if (shouldUpdate(node, oldNode)) {
      if (typeof node === "string") {
        element.textContent = node
      } else {
        parent.replaceChild(createElementFrom(node), element)
      }

    } else if (node.tag) {
      updateElementData(element, node.data, oldNode.data)

      var len = node.children.length, oldLen = oldNode.children.length

      for (var i = 0; i < len || i < oldLen; i++) {
        patch(element, oldNode.children[i], node.children[i], i)
      }
    }
  }
}
<commit_msg>Use != null for less bytes.<commit_after>var SVG_NS = "http://www.w3.org/2000/svg"

export default function (app) {
  var view = app.view || function () {
    return ""
  }

  var model
  var actions = {}
  var subscriptions = []
  var hooks = {
    onError: [],
    onAction: [],
    onUpdate: [],
    onRender: []
  }

  var node
  var root
  var batch = []
  var plugins = app.plugins || []

  for (var i = -1; i < plugins.length; i++) {
    var plugin = i < 0 ? app : plugins[i](app)

    if (plugin.model != null) {
      model = merge(model, plugin.model)
    }

    if (plugin.actions) {
      init(actions, plugin.actions)
    }

    if (plugin.subscriptions) {
      subscriptions = subscriptions.concat(plugin.subscriptions)
    }

    var _hooks = plugin.hooks
    if (_hooks) {
      Object.keys(_hooks).forEach(function (key) {
        hooks[key].push(_hooks[key])
      })
    }
  }

  function onError(error) {
    for (var i = 0; i < hooks.onError.length; i++) {
      hooks.onError[i](error)
    }

    if (i <= 0) {
      throw error
    }
  }

  function init(container, group, lastName) {
    Object.keys(group).forEach(function (key) {
      if (!container[key]) {
        container[key] = {}
      }

      var name = lastName ? lastName + "." + key : key
      var action = group[key]
      var i

      if (typeof action === "function") {
        container[key] = function (data) {
          for (i = 0; i < hooks.onAction.length; i++) {
            hooks.onAction[i](name, data)
          }

          var result = action(model, data, actions, onError)

          if (result == null || typeof result.then === "function") {
            return result

          } else {
            for (i = 0; i < hooks.onUpdate.length; i++) {
              hooks.onUpdate[i](model, result, data)
            }

            model = merge(model, result)
            render(model, view)
          }
        }
      } else {
        init(container[key], action, name)
      }
    })
  }

  load(function () {
    root = app.root || document.body.appendChild(document.createElement("div"))

    render(model, view)

    for (var i = 0; i < subscriptions.length; i++) {
      subscriptions[i](model, actions, onError)
    }
  })

  function load(fn) {
    if (document.readyState[0] !== "l") {
      fn()
    } else {
      document.addEventListener("DOMContentLoaded", fn)
    }
  }

  function render(model, view) {
    for (i = 0; i < hooks.onRender.length; i++) {
      view = hooks.onRender[i](model, view)
    }

    patch(root, node, node = view(model, actions), 0)

    for (var i = 0; i < batch.length; i++) {
      batch[i]()
    }

    batch = []
  }

  function merge(a, b) {
    var obj = {}
    var key

    if (isPrimitive(b) || Array.isArray(b)) {
      return b
    }

    for (key in a) {
      obj[key] = a[key]
    }
    for (key in b) {
      obj[key] = b[key]
    }

    return obj
  }

  function isPrimitive(type) {
    type = typeof type
    return type === "string" || type === "number" || type === "boolean"
  }

  function defer(fn, data) {
    setTimeout(function () {
      fn(data)
    }, 0)
  }

  function shouldUpdate(a, b) {
    return a.tag !== b.tag || typeof a !== typeof b || isPrimitive(a) && a !== b
  }

  function createElementFrom(node, isSVG) {
    var element

    if (typeof node === "string") {
      element = document.createTextNode(node)

    } else {
      element = (isSVG = isSVG || node.tag === "svg")
        ? document.createElementNS(SVG_NS, node.tag)
        : document.createElement(node.tag)

      for (var name in node.data) {
        if (name === "onCreate") {
          defer(node.data[name], element)
        } else {
          setElementData(element, name, node.data[name])
        }
      }

      for (var i = 0; i < node.children.length; i++) {
        element.appendChild(createElementFrom(node.children[i], isSVG))
      }
    }

    return element
  }

  function removeElementData(element, name, value) {
    element[name] = value
    element.removeAttribute(name)
  }

  function setElementData(element, name, value, oldValue) {
    name = name.toLowerCase()

    if (!value) {
      removeElementData(element, name, value, oldValue)

    } else if (name === "style") {
      for (var i in oldValue) {
        if (!(i in value)) {
          element.style[i] = ""
        }
      }

      for (var i in value) {
        element.style[i] = value[i]
      }
    } else {
      element.setAttribute(name, value)

      if (element.namespaceURI !== SVG_NS) {
        if (element.type === "text") {
          var oldSelStart = element.selectionStart
          var oldSelEnd = element.selectionEnd
        }

        element[name] = value

        if (oldSelStart >= 0) {
          element.setSelectionRange(oldSelStart, oldSelEnd)
        }
      }
    }
  }

  function updateElementData(element, data, oldData) {
    for (var name in merge(oldData, data)) {
      var value = data[name]
      var oldValue = oldData[name]
      var realValue = element[name]

      if (name === "onUpdate") {
        defer(value, element)

      } else if (
        value !== oldValue || typeof realValue === "boolean" && realValue !== value
      ) {
        setElementData(element, name, value, oldValue)
      }
    }
  }

  function patch(parent, oldNode, node, index) {
    var element = parent.childNodes[index]

    if (oldNode === undefined) {
      parent.appendChild(createElementFrom(node))

    } else if (node === undefined) {
      // Removing a child one at a time updates the DOM, so we end up
      // with an index out of date that needs to be adjusted. Instead,
      // collect all the elements and delete them in a batch.

      batch.push(parent.removeChild.bind(parent, element))

      if (oldNode && oldNode.data && oldNode.data.onRemove) {
        defer(oldNode.data.onRemove, element)
      }

    } else if (shouldUpdate(node, oldNode)) {
      if (typeof node === "string") {
        element.textContent = node
      } else {
        parent.replaceChild(createElementFrom(node), element)
      }

    } else if (node.tag) {
      updateElementData(element, node.data, oldNode.data)

      var len = node.children.length, oldLen = oldNode.children.length

      for (var i = 0; i < len || i < oldLen; i++) {
        patch(element, oldNode.children[i], node.children[i], i)
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';
const Promise = require('bluebird');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');

const fs = Promise.promisifyAll(require('fs'));
const vecka = require('vecka');

const maya = require('./maya.js');

function mailBody(week, times, person) {
    return `Hej,

Tidrapport för v${week}

Visby: ${times.visby}h
Stockholm: ${times.distans}h

Totalt: ${times.total}h

Mvh
${person.firstName} ${person.familyName}`;
}

function getWeekNumber(d) {
    // Copy date so don't modify original
    d = new Date(+d);
    d.setHours(0,0,0);
    // Set to nearest Thursday: current date + 4 - current day number
    // Make Sunday's day number 7
    d.setDate(d.getDate() + 4 - (d.getDay()||7));
    // Get first day of year
    var yearStart = new Date(d.getFullYear(),0,1);
    // Calculate full weeks to nearest Thursday
    var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
    // Return array of year and week number
    return [d.getFullYear(), weekNo];
}

app.use(bodyParser.urlencoded({
    extended: true
}));

app.use(function (req, res, next) {
    const isProduction = process.env.NODE_ENV === 'production';

    if (isProduction && req.header('x-forwarded-proto') !== 'https') {
        return res.redirect(`https://${req.get('Host')}${req.url}`);
    }

    next();
});

app.use('/styles.css', express.static('views/styles.css'));
app.use('/login', express.static('views/login.html'));

app.post('/login',  (req, res) => {
    const refererUrl = (req.headers.referer || '');
    const backUrl = refererUrl.indexOf('?referer=') < 0
        ? '/'
        : refererUrl.substring(refererUrl.indexOf('?referer=') + '?referer='.length);

    maya
        .login(req.body.Username, req.body.Password)
        .then(cookie => {
            res.header('set-cookie', cookie);
            res.redirect(backUrl);
        })
        .catch(err => {
            res.status(400);
            res.redirect('/login');
        })
});

app.get('/logout', (req, res) => {
    const cookie = req.headers.cookie;

    if (!cookie) return res.redirect('/');

    maya.logout(cookie)
        .then(result => {
            res.redirect('/login');
        })
        .catch(err => {
            res.status(400);
            res.redirect('/');
        });
});

app.get('/:year/:week', function(req, res) {
    const cookie = req.headers.cookie;

    if (!cookie) return res.redirect('/login');

    const year = parseInt(req.params.year);
    const week = parseInt(req.params.week);

    Promise.join(
        maya.person(cookie),
        maya.timeReportingYearWeek(cookie, year, week),
        fs.readFileAsync('views/report.html', 'UTF-8'),
        (person, times, reportHtmlTemplateBuffer) => {
            const mail = mailBody(week, times, person);
            const mailString = '\'' + mail.replace(/\n/g, '\\n') + '\'';
            const mailBr = mail.replace(/\n/g, '
');
            const mailHref = mail.replace(/\n/g, '%0D%0A');

            const reportHtml = reportHtmlTemplateBuffer.toString()
                .replace(new RegExp('\\$\\{week\\}', 'g'), week)
                .replace(new RegExp('\\$\\{mailString\\}', 'g'), mailString)
                .replace(new RegExp('\\$\\{mailBr\\}', 'g'), mailBr)
                .replace(new RegExp('\\$\\{mailHref\\}', 'g'), mailHref);

            res.setHeader('Content-Type', 'text/html');
            res.send(reportHtml);
    })
    .catch(err => {
        if (err === 'invalid html' || err.res) {
            return res.redirect('/login?referer=' + req.url);
        }

        console.error('Error', err);

        res.status(500);
        res.send(err);
    })
});

app.get('*', function(req, res) {
    const year = new Date().getFullYear();
    const week = getWeekNumber(new Date());

    res.redirect(`/${year}/${week}`);
});

app.listen(process.env.PORT || 3000);

console.log('nilleglad started in', process.env.NODE_ENV || 'development', 'mode');

<commit_msg>Weeknumber is timezone independent<commit_after>'use strict';
const Promise = require('bluebird');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');

const fs = Promise.promisifyAll(require('fs'));
const vecka = require('vecka');

const maya = require('./maya.js');

function mailBody(week, times, person) {
    return `Hej,

Tidrapport för v${week}

Visby: ${times.visby}h
Stockholm: ${times.distans}h

Totalt: ${times.total}h

Mvh
${person.firstName} ${person.familyName}`;
}

function getWeekNumber(date) {
    const target = new Date(date.valueOf());
    const dayNumber = (date.getUTCDay() + 6) % 7;

    target.setUTCDate(target.getUTCDate() - dayNumber + 3);

    const firstThursday = target.valueOf();

    target.setUTCMonth(0, 1);

    if (target.getUTCDay() !== 4) {
        target.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7);
    }

    return Math.ceil((firstThursday - target) /  (7 * 24 * 3600 * 1000)) + 1;
}

app.use(bodyParser.urlencoded({
    extended: true
}));

app.use(function (req, res, next) {
    const isProduction = process.env.NODE_ENV === 'production';

    if (isProduction && req.header('x-forwarded-proto') !== 'https') {
        return res.redirect(`https://${req.get('Host')}${req.url}`);
    }

    next();
});

app.use('/styles.css', express.static('views/styles.css'));
app.use('/login', express.static('views/login.html'));

app.post('/login',  (req, res) => {
    const refererUrl = (req.headers.referer || '');
    const backUrl = refererUrl.indexOf('?referer=') < 0
        ? '/'
        : refererUrl.substring(refererUrl.indexOf('?referer=') + '?referer='.length);

    maya
        .login(req.body.Username, req.body.Password)
        .then(cookie => {
            res.header('set-cookie', cookie);
            res.redirect(backUrl);
        })
        .catch(err => {
            res.status(400);
            res.redirect('/login');
        })
});

app.get('/logout', (req, res) => {
    const cookie = req.headers.cookie;

    if (!cookie) return res.redirect('/');

    maya.logout(cookie)
        .then(result => {
            res.redirect('/login');
        })
        .catch(err => {
            res.status(400);
            res.redirect('/');
        });
});

app.get('/:year/:week', function(req, res) {
    const cookie = req.headers.cookie;

    if (!cookie) return res.redirect('/login');

    const year = parseInt(req.params.year);
    const week = parseInt(req.params.week);

    Promise.join(
        maya.person(cookie),
        maya.timeReportingYearWeek(cookie, year, week),
        fs.readFileAsync('views/report.html', 'UTF-8'),
        (person, times, reportHtmlTemplateBuffer) => {
            const mail = mailBody(week, times, person);
            const mailString = '\'' + mail.replace(/\n/g, '\\n') + '\'';
            const mailBr = mail.replace(/\n/g, '
');
            const mailHref = mail.replace(/\n/g, '%0D%0A');

            const reportHtml = reportHtmlTemplateBuffer.toString()
                .replace(new RegExp('\\$\\{week\\}', 'g'), week)
                .replace(new RegExp('\\$\\{mailString\\}', 'g'), mailString)
                .replace(new RegExp('\\$\\{mailBr\\}', 'g'), mailBr)
                .replace(new RegExp('\\$\\{mailHref\\}', 'g'), mailHref);

            res.setHeader('Content-Type', 'text/html');
            res.send(reportHtml);
    })
    .catch(err => {
        if (err === 'invalid html' || err.res) {
            return res.redirect('/login?referer=' + req.url);
        }

        console.error('Error', err);

        res.status(500);
        res.send(err);
    })
});

app.get('*', function(req, res) {
    const year = new Date().getFullYear();
    const week = getWeekNumber(new Date());

    res.redirect(`/${year}/${week}`);
});

app.listen(process.env.PORT || 3000);

console.log('nilleglad started in', process.env.NODE_ENV || 'development', 'mode');

<|endoftext|>


<commit_before>POOLVR.selectNextBall = function (inc) {
    "use strict";
    inc = inc || 1;
    var next = Math.max(1, Math.min(15, POOLVR.nextBall + inc));
    while (!POOLVR.onTable[next]) {
        next = Math.max(1, Math.min(15, next + inc));
        if (next === POOLVR.nextBall) {
            break;
        }
    }
    if (POOLVR.nextBall !== next) {
        POOLVR.nextBall = next;
        POOLVR.textGeomLogger.log("BALL " + POOLVR.nextBall + " SELECTED");
    }
};

POOLVR.resetTable = function () {
    "use strict";
    POOLVR.ballBodies.forEach(function (body, ballNum) {
        body.wakeUp();
        body.position.copy(POOLVR.initialPositions[ballNum]);
        body.velocity.set(0, 0, 0);
        body.angularVelocity.set(0, 0, 0);
        body.bounces = 0;
        POOLVR.onTable[ballNum] = true;
        body.mesh.visible = true;
    });
    if (POOLVR.synthSpeaker.speaking === false) {
        POOLVR.synthSpeaker.speak("Table reset.");
    }
    POOLVR.nextBall = 1;
    POOLVR.textGeomLogger.log("TABLE RESET.");
};

POOLVR.avatar = new THREE.Object3D();

POOLVR.autoPosition = ( function () {
    "use strict";
    var nextVector = new THREE.Vector3();
    var UP = new THREE.Vector3(0, 1, 0);
    var avatar = POOLVR.avatar;
    return function () {
        // POOLVR.textGeomLogger.log("YOU ARE BEING AUTO-POSITIONED.  NEXT BALL: " + POOLVR.nextBall);
        if (POOLVR.synthSpeaker.speaking === false) {
            POOLVR.synthSpeaker.speak("You are being auto-positioned.");
        }

        avatar.heading = Math.atan2(
            -(POOLVR.ballMeshes[POOLVR.nextBall].position.x - POOLVR.ballMeshes[0].position.x),
            -(POOLVR.ballMeshes[POOLVR.nextBall].position.z - POOLVR.ballMeshes[0].position.z)
        );
        avatar.quaternion.setFromAxisAngle(UP, avatar.heading);
        avatar.updateMatrixWorld();

        nextVector.copy(POOLVR.toolRoot.position);
        avatar.localToWorld(nextVector);
        nextVector.sub(POOLVR.ballMeshes[0].position);
        nextVector.y = 0;
        avatar.position.sub(nextVector);
    };
} )();

POOLVR.moveAvatar = ( function () {
    "use strict";
    var UP = new THREE.Vector3(0, 1, 0),
        walkSpeed = 0.333,
        floatSpeed = 0.1;
    var avatar = POOLVR.avatar;

    return function (keyboard, gamepad, dt) {
        var floatUp = keyboard.getValue("floatUp") + keyboard.getValue("floatDown");
        var drive = keyboard.getValue("driveBack") + keyboard.getValue("driveForward");
        var strafe = keyboard.getValue("strafeRight") + keyboard.getValue("strafeLeft");
        var heading = -0.8 * dt * (keyboard.getValue("turnLeft") + keyboard.getValue("turnRight"));
        if (avatar.floatMode) {
            floatUp += gamepad.getValue("float");
            strafe += gamepad.getValue("strafe");
        } else {
            drive += gamepad.getValue("drive");
            heading += 0.8 * dt * gamepad.getValue("dheading");
        }
        floatUp *= floatSpeed;
        if (strafe || drive) {
            var len = walkSpeed * Math.min(1, 1 / Math.sqrt(drive * drive + strafe * strafe));
            strafe *= len;
            drive *= len;
        } else {
            strafe = 0;
            drive = 0;
        }
        if (floatUp !== 0 || strafe !== 0 || heading !== 0 || drive !== 0) {
            avatar.heading += heading;
            var cosHeading = Math.cos(avatar.heading),
                sinHeading = Math.sin(avatar.heading);
            avatar.quaternion.setFromAxisAngle(UP, avatar.heading);
            avatar.position.x += dt * (strafe * cosHeading + drive * sinHeading);
            avatar.position.z += dt * (drive * cosHeading - strafe * sinHeading);
            avatar.position.y += dt * floatUp;
        }
    };
} )();

POOLVR.startTutorial = function () {
    "use strict";
    POOLVR.synthSpeaker.speak("Hello.  Welcome. To. Pool-ver.", function () {
        POOLVR.textGeomLogger.log("HELLO.  WELCOME TO POOLVR.");
    });

    POOLVR.synthSpeaker.speak("Please wave a stick-like object in front of your Leap Motion controller.", function () {
        POOLVR.textGeomLogger.log("PLEASE WAVE A STICK-LIKE OBJECT IN FRONT OF YOUR");
        POOLVR.textGeomLogger.log("LEAP MOTION CONTROLLER.");
    });

    POOLVR.synthSpeaker.speak("Keep the stick within the interaction box when you want to make contact with.  A ball.", function () {
        POOLVR.textGeomLogger.log("KEEP THE STICK WITHIN THE INTERACTION BOX WHEN YOU WANT");
        POOLVR.textGeomLogger.log("TO MAKE CONTACT WITH A BALL...");
    });
};

POOLVR.animate = function () {
    "use strict";
    var keyboard = POOLVR.keyboard,
        gamepad  = POOLVR.gamepad,
        app      = POOLVR.app,
        world    = POOLVR.world,
        updateTool          = POOLVR.updateTool,
        updateToolPostStep  = POOLVR.updateToolPostStep,
        moveToolRoot        = POOLVR.moveToolRoot,
        moveAvatar          = POOLVR.moveAvatar,
        updateBallsPostStep = POOLVR.updateBallsPostStep;

    var glS, rS;
    if (URL_PARAMS.rstats) {
        /* jshint ignore:start */
        var tS = new threeStats( POOLVR.app.renderer );
        glS = new glStats();
        rS  = new rStats({
            CSSPath: "lib/rstats/",
            values: {
                frame: { caption: 'Total frame time (ms)' },
                calls: { caption: 'Calls (three.js)' },
                raf: { caption: 'Time since last rAF (ms)' },
                // rstats: { caption: 'rStats update (ms)' }, // no worky?
                updatetool: { caption: 'Leap frame update (ms)' },
                updatevrcontrols: { caption: 'VRControls update (ms)' },
                step: { caption: 'Cannon step (ms)' },
                poststep: { caption: 'Cannon post-step (ms)' },
                updatekeyboardgamepad: { caption: 'Move avatar / Leap (ms)' }
            },
            fractions: [
                { base: 'frame', steps: [ 'updatetool', 'updatevrcontrols', 'render', 'step', 'poststep', 'updatekeyboardgamepad' ] }
            ],
            plugins: [tS, glS]
        });
        /* jshint ignore:end */
    } else {
        glS = {start: function () {}};
        rS  = function (id) { return {start:  function () {},
                                      end:    function () {},
                                      tick:   function () {},
                                      frame:  function () {},
                                      update: function () {}}; };
    }

    var lt = 0;

    function animate(t) {
        rS('frame').start();
        glS.start();
        rS('raf').tick();
        rS('fps').frame();

        var dt = (t - lt) * 0.001;

        rS('updatetool').start();
        updateTool();
        rS('updatetool').end();

        rS('updatevrcontrols').start();
        if (app.vrControls.enabled) {
            app.vrControls.update();
        }
        rS('updatevrcontrols').end();

        rS('render').start();
        app.vrManager.render(app.scene, app.camera, t);
        rS('render').end();

        requestAnimationFrame(animate);

        rS('step').start();
        //world.step(dt);
        //world.step(1/75, dt, 5);
        world.step(1/60, dt, 5);
        rS('step').end();

        rS('poststep').start();
        updateToolPostStep();
        updateBallsPostStep();
        rS('poststep').end();

        rS('updatekeyboardgamepad').start();
        keyboard.update(dt);
        gamepad.update(dt);

        moveAvatar(keyboard, gamepad, dt);
        moveToolRoot(keyboard, gamepad, dt);
        rS('updatekeyboardgamepad').end();

        lt = t;

        rS('frame').end();
        rS().update();
    }

    return animate;

};

function onLoad() {
    "use strict";

    POOLVR.loadConfig();
    console.log("POOLVR.config =\n" + JSON.stringify(POOLVR.config, undefined, 2));

    var avatar = POOLVR.avatar;
    avatar.position.fromArray(POOLVR.config.initialPosition);
    avatar.heading = 0;
    avatar.floatMode = false;
    avatar.toolMode = false;

    POOLVR.synthSpeaker = new SynthSpeaker({volume: POOLVR.config.synthSpeakerVolume, rate: 0.8, pitch: 0.5});

    if (POOLVR.config.useTextGeomLogger) {
        var fontLoader = new THREE.FontLoader();
        fontLoader.load('fonts/Anonymous Pro_Regular.js', function (font) {
            var textGeomCacher = new TextGeomUtils.TextGeomCacher(font, {size: 0.12});
            var textGeomLoggerMaterial = new THREE.MeshBasicMaterial({color: 0xff3210});
            POOLVR.textGeomLogger = new TextGeomUtils.TextGeomLogger(textGeomCacher,
                {material: textGeomLoggerMaterial, nrows: 7, lineHeight: 1.8 * 0.12});
            avatar.add(POOLVR.textGeomLogger.root);
            POOLVR.textGeomLogger.root.position.set(-2.5, 1.0, -3.5);
        });
    } else {
        POOLVR.textGeomLogger = {
            root: new THREE.Object3D(),
            log: function (msg) { console.log(msg); },
            clear: function () {}
        };
    }

    THREE.py.parse(THREEPY_SCENE).then( function (scene) {

        if (!POOLVR.config.useBasicMaterials) {
            var centerSpotLight = new THREE.SpotLight(0xffffee, 1, 8, Math.PI / 2);
            centerSpotLight.position.set(0, 3, 0);
            centerSpotLight.castShadow = true;
            centerSpotLight.shadow.camera.near = 0.01;
            centerSpotLight.shadow.camera.far = 4;
            centerSpotLight.shadow.camera.fov = 90;
            scene.add(centerSpotLight);
        }

        if (POOLVR.config.usePointLight) {
            var pointLight = new THREE.PointLight(0xaa8866, 0.8, 40);
            pointLight.position.set(4, 5, 2.5);
            scene.add(pointLight);
        }

        var UP = new THREE.Vector3(0, 1, 0);
        var appConfig = combineObjects(POOLVR.config, {
            onResetVRSensor: function (lastRotation, lastPosition) {
                var camera = POOLVR.app.camera;
                // app.camera.updateMatrix();
                POOLVR.avatar.heading += lastRotation - camera.rotation.y;
                POOLVR.toolRoot.rotation.y -= (lastRotation - camera.rotation.y);
                POOLVR.toolRoot.position.sub(lastPosition);
                POOLVR.toolRoot.position.applyAxisAngle(UP, -lastRotation + camera.rotation.y);
                POOLVR.toolRoot.position.add(camera.position);
                // POOLVR.toolRoot.updateMatrix();
                POOLVR.avatar.updateMatrixWorld();
            }
        });

        POOLVR.app = new WebVRApplication(scene, appConfig);

        avatar.add(POOLVR.app.camera);
        scene.add(avatar);

        POOLVR.setup();

        requestAnimationFrame( POOLVR.animate() );

        POOLVR.startTutorial();

    } );

}
<commit_msg>startanimateloop<commit_after>POOLVR.selectNextBall = function (inc) {
    "use strict";
    inc = inc || 1;
    var next = Math.max(1, Math.min(15, POOLVR.nextBall + inc));
    while (!POOLVR.onTable[next]) {
        next = Math.max(1, Math.min(15, next + inc));
        if (next === POOLVR.nextBall) {
            break;
        }
    }
    if (POOLVR.nextBall !== next) {
        POOLVR.nextBall = next;
        POOLVR.textGeomLogger.log("BALL " + POOLVR.nextBall + " SELECTED");
    }
};

POOLVR.resetTable = function () {
    "use strict";
    POOLVR.ballBodies.forEach(function (body, ballNum) {
        body.wakeUp();
        body.position.copy(POOLVR.initialPositions[ballNum]);
        body.velocity.set(0, 0, 0);
        body.angularVelocity.set(0, 0, 0);
        body.bounces = 0;
        POOLVR.onTable[ballNum] = true;
        body.mesh.visible = true;
    });
    if (POOLVR.synthSpeaker.speaking === false) {
        POOLVR.synthSpeaker.speak("Table reset.");
    }
    POOLVR.nextBall = 1;
    POOLVR.textGeomLogger.log("TABLE RESET.");
};

POOLVR.avatar = new THREE.Object3D();

POOLVR.autoPosition = ( function () {
    "use strict";
    var nextVector = new THREE.Vector3();
    var UP = new THREE.Vector3(0, 1, 0);
    var avatar = POOLVR.avatar;
    return function () {
        // POOLVR.textGeomLogger.log("YOU ARE BEING AUTO-POSITIONED.  NEXT BALL: " + POOLVR.nextBall);
        if (POOLVR.synthSpeaker.speaking === false) {
            POOLVR.synthSpeaker.speak("You are being auto-positioned.");
        }

        avatar.heading = Math.atan2(
            -(POOLVR.ballMeshes[POOLVR.nextBall].position.x - POOLVR.ballMeshes[0].position.x),
            -(POOLVR.ballMeshes[POOLVR.nextBall].position.z - POOLVR.ballMeshes[0].position.z)
        );
        avatar.quaternion.setFromAxisAngle(UP, avatar.heading);
        avatar.updateMatrixWorld();

        nextVector.copy(POOLVR.toolRoot.position);
        avatar.localToWorld(nextVector);
        nextVector.sub(POOLVR.ballMeshes[0].position);
        nextVector.y = 0;
        avatar.position.sub(nextVector);
    };
} )();

POOLVR.moveAvatar = ( function () {
    "use strict";
    var UP = new THREE.Vector3(0, 1, 0),
        walkSpeed = 0.333,
        floatSpeed = 0.1;
    var avatar = POOLVR.avatar;

    return function (keyboard, gamepad, dt) {
        var floatUp = keyboard.getValue("floatUp") + keyboard.getValue("floatDown");
        var drive = keyboard.getValue("driveBack") + keyboard.getValue("driveForward");
        var strafe = keyboard.getValue("strafeRight") + keyboard.getValue("strafeLeft");
        var heading = -0.8 * dt * (keyboard.getValue("turnLeft") + keyboard.getValue("turnRight"));
        if (avatar.floatMode) {
            floatUp += gamepad.getValue("float");
            strafe += gamepad.getValue("strafe");
        } else {
            drive += gamepad.getValue("drive");
            heading += 0.8 * dt * gamepad.getValue("dheading");
        }
        floatUp *= floatSpeed;
        if (strafe || drive) {
            var len = walkSpeed * Math.min(1, 1 / Math.sqrt(drive * drive + strafe * strafe));
            strafe *= len;
            drive *= len;
        } else {
            strafe = 0;
            drive = 0;
        }
        if (floatUp !== 0 || strafe !== 0 || heading !== 0 || drive !== 0) {
            avatar.heading += heading;
            var cosHeading = Math.cos(avatar.heading),
                sinHeading = Math.sin(avatar.heading);
            avatar.quaternion.setFromAxisAngle(UP, avatar.heading);
            avatar.position.x += dt * (strafe * cosHeading + drive * sinHeading);
            avatar.position.z += dt * (drive * cosHeading - strafe * sinHeading);
            avatar.position.y += dt * floatUp;
        }
    };
} )();

POOLVR.startTutorial = function () {
    "use strict";
    POOLVR.synthSpeaker.speak("Hello.  Welcome. To. Pool-ver.", function () {
        POOLVR.textGeomLogger.log("HELLO.  WELCOME TO POOLVR.");
    });

    POOLVR.synthSpeaker.speak("Please wave a stick-like object in front of your Leap Motion controller.", function () {
        POOLVR.textGeomLogger.log("PLEASE WAVE A STICK-LIKE OBJECT IN FRONT OF YOUR");
        POOLVR.textGeomLogger.log("LEAP MOTION CONTROLLER.");
    });

    POOLVR.synthSpeaker.speak("Keep the stick within the interaction box when you want to make contact with.  A ball.", function () {
        POOLVR.textGeomLogger.log("KEEP THE STICK WITHIN THE INTERACTION BOX WHEN YOU WANT");
        POOLVR.textGeomLogger.log("TO MAKE CONTACT WITH A BALL...");
    });
};

POOLVR.startAnimateLoop = function () {
    "use strict";
    var keyboard = POOLVR.keyboard,
        gamepad  = POOLVR.gamepad,
        app      = POOLVR.app,
        world    = POOLVR.world,
        updateTool          = POOLVR.updateTool,
        updateToolPostStep  = POOLVR.updateToolPostStep,
        moveToolRoot        = POOLVR.moveToolRoot,
        moveAvatar          = POOLVR.moveAvatar,
        updateBallsPostStep = POOLVR.updateBallsPostStep;

    var glS, rS;
    if (URL_PARAMS.rstats) {
        /* jshint ignore:start */
        var tS = new threeStats( POOLVR.app.renderer );
        glS = new glStats();
        rS  = new rStats({
            CSSPath: "lib/rstats/",
            values: {
                frame: { caption: 'Total frame time (ms)' },
                calls: { caption: 'Calls (three.js)' },
                raf: { caption: 'Time since last rAF (ms)' },
                // rstats: { caption: 'rStats update (ms)' }, // no worky?
                updatetool: { caption: 'Leap frame update (ms)' },
                updatevrcontrols: { caption: 'VRControls update (ms)' },
                step: { caption: 'Cannon step (ms)' },
                poststep: { caption: 'Cannon post-step (ms)' },
                updatekeyboardgamepad: { caption: 'Move avatar / Leap (ms)' }
            },
            fractions: [
                { base: 'frame', steps: [ 'updatetool', 'updatevrcontrols', 'render', 'step', 'poststep', 'updatekeyboardgamepad' ] }
            ],
            plugins: [tS, glS]
        });
        /* jshint ignore:end */
    } else {
        glS = {start: function () {}};
        rS  = function (id) { return {start:  function () {},
                                      end:    function () {},
                                      tick:   function () {},
                                      frame:  function () {},
                                      update: function () {}}; };
    }

    var lt = 0;

    function animate(t) {
        rS('frame').start();
        glS.start();
        rS('raf').tick();
        rS('fps').frame();

        var dt = (t - lt) * 0.001;

        rS('updatetool').start();
        updateTool();
        rS('updatetool').end();

        rS('updatevrcontrols').start();
        if (app.vrControls.enabled) {
            app.vrControls.update();
        }
        rS('updatevrcontrols').end();

        rS('render').start();
        app.vrManager.render(app.scene, app.camera, t);
        rS('render').end();

        requestAnimationFrame(animate);

        rS('step').start();
        //world.step(dt);
        //world.step(1/75, dt, 5);
        world.step(1/60, dt, 5);
        rS('step').end();

        rS('poststep').start();
        updateToolPostStep();
        updateBallsPostStep();
        rS('poststep').end();

        rS('updatekeyboardgamepad').start();
        keyboard.update(dt);
        gamepad.update(dt);

        moveAvatar(keyboard, gamepad, dt);
        moveToolRoot(keyboard, gamepad, dt);
        rS('updatekeyboardgamepad').end();

        lt = t;

        rS('frame').end();
        rS().update();
    }

    requestAnimationFrame(animate);

};

function onLoad() {
    "use strict";

    POOLVR.loadConfig();
    console.log("POOLVR.config =\n" + JSON.stringify(POOLVR.config, undefined, 2));

    var avatar = POOLVR.avatar;
    avatar.position.fromArray(POOLVR.config.initialPosition);
    avatar.heading = 0;
    avatar.floatMode = false;
    avatar.toolMode = false;

    POOLVR.synthSpeaker = new SynthSpeaker({volume: POOLVR.config.synthSpeakerVolume, rate: 0.8, pitch: 0.5});

    if (POOLVR.config.useTextGeomLogger) {
        var fontLoader = new THREE.FontLoader();
        fontLoader.load('fonts/Anonymous Pro_Regular.js', function (font) {
            var textGeomCacher = new TextGeomUtils.TextGeomCacher(font, {size: 0.12});
            var textGeomLoggerMaterial = new THREE.MeshBasicMaterial({color: 0xff3210});
            POOLVR.textGeomLogger = new TextGeomUtils.TextGeomLogger(textGeomCacher,
                {material: textGeomLoggerMaterial, nrows: 7, lineHeight: 1.8 * 0.12});
            avatar.add(POOLVR.textGeomLogger.root);
            POOLVR.textGeomLogger.root.position.set(-2.5, 1.0, -3.5);
        });
    } else {
        POOLVR.textGeomLogger = {
            root: new THREE.Object3D(),
            log: function (msg) { console.log(msg); },
            clear: function () {}
        };
    }

    THREE.py.parse(THREEPY_SCENE).then( function (scene) {

        if (!POOLVR.config.useBasicMaterials) {
            var centerSpotLight = new THREE.SpotLight(0xffffee, 1, 8, Math.PI / 2);
            centerSpotLight.position.set(0, 3, 0);
            centerSpotLight.castShadow = true;
            centerSpotLight.shadow.camera.near = 0.01;
            centerSpotLight.shadow.camera.far = 4;
            centerSpotLight.shadow.camera.fov = 90;
            scene.add(centerSpotLight);
        }

        if (POOLVR.config.usePointLight) {
            var pointLight = new THREE.PointLight(0xaa8866, 0.8, 40);
            pointLight.position.set(4, 5, 2.5);
            scene.add(pointLight);
        }

        var UP = new THREE.Vector3(0, 1, 0);
        var appConfig = combineObjects(POOLVR.config, {
            onResetVRSensor: function (lastRotation, lastPosition) {
                var camera = POOLVR.app.camera;
                // app.camera.updateMatrix();
                POOLVR.avatar.heading += lastRotation - camera.rotation.y;
                POOLVR.toolRoot.rotation.y -= (lastRotation - camera.rotation.y);
                POOLVR.toolRoot.position.sub(lastPosition);
                POOLVR.toolRoot.position.applyAxisAngle(UP, -lastRotation + camera.rotation.y);
                POOLVR.toolRoot.position.add(camera.position);
                // POOLVR.toolRoot.updateMatrix();
                POOLVR.avatar.updateMatrixWorld();
            }
        });

        POOLVR.app = new WebVRApplication(scene, appConfig);

        avatar.add(POOLVR.app.camera);
        scene.add(avatar);

        POOLVR.setup();

        POOLVR.startAnimateLoop();

        POOLVR.startTutorial();

    } );

}
<|endoftext|>


<commit_before>App = {
  placeAnchorHooks : function() {
    $('[data-href]').on('click',function() {
      App.Router.navigate( $(this).attr('data-href'), true );
      _.delay(function() { window.scrollTo(0,0); }, 250);
    });
  }
};

$(document).ready(function() {
  App.Router = new Router;
  Backbone.history.start({ pushState: true });

  App.placeAnchorHooks();

  setTimeout(function() { window.scrollTo(0, 0); }, 1000);
  $(window).bind('orientationchange', function() { scrollTo(0, 0); });
});<commit_msg>Disable pushState for file: protocl URLs<commit_after>App = {
  placeAnchorHooks : function() {
    $('[data-href]').on('click',function() {
      App.Router.navigate( $(this).attr('data-href'), true );
      _.delay(function() { window.scrollTo(0,0); }, 250);
    });
  }
};

$(document).ready(function() {
  App.Router = new Router;
  Backbone.history.start({ pushState: location.href.indexOf("file://") !== 0 });

  App.placeAnchorHooks();

  setTimeout(function() { window.scrollTo(0, 0); }, 1000);
  $(window).bind('orientationchange', function() { scrollTo(0, 0); });
});<|endoftext|>