<commit_before>/**
  The MIT License (MIT)

  Copyright (c) 2015 Jeppe Rune Mortensen

  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
  the Software without restriction, including without limitation the rights to
  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  the Software, and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**/

// ==UserScript==
// @id              agarz
// @name            agarz extras
// @namespace       http://www.facebook.com/richirm
// @version         0.0.16
// @author          richirm
// @description     Agrega funcionalidades para agarz
// @icon            https://raw.githubusercontent.com/richirm/agarz/master/src/assets/img/t%26p.png
// @domain          http://www.facebook.com/richirm
// @match           http://agarz.com/
// @include         http://agarz.com/
// @grant           none
// @updateURL       https://raw.githubusercontent.com/richirm/agarz/master/src/app/agarz.user.js
// @downloadURL     https://raw.githubusercontent.com/richirm/agarz/master/src/app/agarz.user.js
// @run-at          document-end
// @priority        9001
// @contributionURL https://github.com/richirm/agarz/wiki/Donate
// ==/UserScript==

// The source code of agarz can be found at https://github.com/richirm/agarz/
//

/*global window */

(function () {
	'use strict';

	window.console.log('agarz');

	var intervalMain = window.setInterval(function () {
		if (!!window.onkeydown) {
			window.setTimeout(function () {
				var head = window.$('head').html().
					replace('main20obf.js','https://dl.dropboxusercontent.com/u/65999952/agarz.main.js'),
					body = window.$('body').html();

				window.$('head >, body >').remove();

				window.$('body').append(body);
				window.$('head').append(head);
			}, 1000);
			window.clearInterval(intervalMain);
		}
	}, 200);

}());<commit_msg>cambios<commit_after>/**
  The MIT License (MIT)

  Copyright (c) 2015 Jeppe Rune Mortensen

  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
  the Software without restriction, including without limitation the rights to
  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  the Software, and to permit persons to whom the Software is furnished to do so,
  subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**/

// ==UserScript==
// @id              agarz
// @name            agarz extras
// @namespace       http://www.facebook.com/richirm
// @version         0.0.16
// @author          richirm
// @description     Agrega funcionalidades para agarz
// @icon            https://raw.githubusercontent.com/richirm/agarz/master/src/assets/img/t%26p.png
// @domain          http://www.facebook.com/richirm
// @match           http://agarz.com/
// @include         http://agarz.com/
// @grant           none
// @updateURL       https://raw.githubusercontent.com/richirm/agarz/master/src/app/agarz.user.js
// @downloadURL     https://raw.githubusercontent.com/richirm/agarz/master/src/app/agarz.user.js
// @run-at          document-end
// @priority        9001
// @contributionURL https://github.com/richirm/agarz/wiki/Donate
// ==/UserScript==

// The source code of agarz can be found at https://github.com/richirm/agarz/
//

/*global window */

(function () {
	'use strict';

	window.console.log('agarz');

	var intervalMain = window.setInterval(function () {
		if (!!window.onkeydown) {
			window.setTimeout(function () {
				var head = window.$('head').html().
					replace(/main(\d*)([a-zA-Z]*).js/,'https://dl.dropboxusercontent.com/u/65999952/agarz.main.js'),
					replace('main20obf.js','https://dl.dropboxusercontent.com/u/65999952/agarz.main.js'),
					body = window.$('body').html();

				window.$('head >, body >').remove();

				window.$('body').append(body);
				window.$('head').append(head);
			}, 1000);
			window.clearInterval(intervalMain);
		}
	}, 200);

}());<|endoftext|>


<commit_before>'use strict'

const inspect = require('inspect.js')
const sinon = require('sinon')
inspect.useSinon(sinon)

const CoreIO = require('../../')
const erroClassArr = require('./errors/errorConf');

describe('Server', () => {
  const fakeReq = {
    accepts() {},
    path: '/foo/bla',
    method: 'GET'
  }

  const fakeRes = {
    status() {},
    send() {}
  }

  describe('use()', () => {
    let server
    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })

      server.use(fn)
      server.use(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next) => { next() })

      server.use(fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('use([path], fn)', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })

      server.use('/foo', fn)
      server.use('/bar', fn)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next) => { next() })

      server.use('/foo', fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('useAfter()', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next, exit) => { exit() })

      server.use(fn)
      server.useAfter(fn3)
      server.use(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3)
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next, exit) => { exit() })

      server.useAfter(fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('useAfter([path], fn)', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true,
        debug: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next, exit) => { exit() })

      server.use('/foo', fn)
      server.useAfter('/foo', fn3)
      server.useAfter('/bar', fn3)
      server.use('/bar', fn)
      server.use('/bar', fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn3)
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next, exit) => { exit() })

      server.use('/foo', fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3, fn4)
      })
    })
  })

  describe('route()', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('should register a route in an internal storage', () => {
      server.route('GET', '/foo/:name', (req, res, next, done) => { done() })

      inspect(server.__routes).isObject()
      inspect(server.__routes.size).isEql(1)
      inspect(server.__routes.get('GET /foo/:name')).hasProps({
        method: 'GET',
        route: '/foo/:name',
        keys: [{
          name: 'name',
          offset: 6,
          optional: false
        }]
      })
    })

    it('should add a route', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      server.route('GET', '/foo/:name', fn)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
      })
    })

    it('should add multiple middlewares', () => {
      const fn = sinon.spy((req, res, next, done) => { next() })
      const fn2 = sinon.spy((req, res, next, done) => { next() })
      const fn3 = sinon.spy((req, res, next, done) => { done() })
      server.route('GET', '/foo/bla', fn, fn2, fn3)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3)
      })
    })
  })

  describe('errorHandler', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })

      server.errorLevel = 1
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('calls an error handler', () => {
      const fn = sinon.spy((req, res, next) => { throw new Error('Fucking error!') })
      const fn2 = sinon.spy((err, req, res, next) => { next() })
      server.use(fn)
      server.errorHandler(fn2)

      return server.dispatch({
        path: '/foo/bla',
        method: 'GET',
        accepts: () => true
      }, {
        status() {},
        send() {}
      }).then(() => {
        inspect(fn2).wasCalledOnce()
      })
    })

    it.skip('never calls an error handler if no error was thrown', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((err, req, res, next) => { console.log(err); next() })
      server.use(fn)
      server.errorHandler(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
      })
    })

    erroClassArr.forEach((test) => {
      it(`calls an final error handler if an ${test.ErrorClass.name} was thrown`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass('Beer is empty!') })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name
          })
        })
      })

      it(`return an extended error for ${test.ErrorClass.name} if level is set to 2`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 2

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name,
            error: test.error
          })
        })
      })

      it(`return an extended error with stack trace for ${test.ErrorClass.name} if level is set to 3`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 3

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name,
            error: test.error,
            stack: sinon.match.string
          })
        })
      })

      it(`calls an final error handler if an ${test.ErrorClass.name} was thrown (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass('Beer is empty!') })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWith(
            `${test.status} ${test.message}`
          )
        })
      })

      it(`return an extended error for ${test.ErrorClass.name} if level is set to 2 (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 2

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWithMatch(
            `${test.status} ${test.message}\n\n${test.error}`
          )
        })
      })

      it(`return an extended error with stack trace for ${test.ErrorClass.name} if level is set to 3 (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 3

        const err = new test.ErrorClass(test.error)
        err.level = 3
        inspect.print(err.toString())
        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWithMatch(
            `${test.status} ${test.message}\n\n${test.error}\n\n${test.status} ${test.message}`
          )
        })
      })
    })
  })
})
<commit_msg>Fix service tests<commit_after>'use strict'

const inspect = require('inspect.js')
const sinon = require('sinon')
inspect.useSinon(sinon)

const CoreIO = require('../../')
const erroClassArr = require('./errors/errorConf');

describe('Server', () => {
  const fakeReq = {
    accepts() {},
    path: '/foo/bla',
    method: 'GET'
  }

  const fakeRes = {
    status() {},
    send() {}
  }

  describe('use()', () => {
    let server
    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })

      server.use(fn)
      server.use(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next) => { next() })

      server.use(fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('use([path], fn)', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })

      server.use('/foo', fn)
      server.use('/bar', fn)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next) => { next() })

      server.use('/foo', fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('useAfter()', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next, exit) => { exit() })

      server.use(fn)
      server.useAfter(fn3)
      server.use(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3)
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next, exit) => { exit() })

      server.useAfter(fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
      })
    })
  })

  describe('useAfter([path], fn)', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true,
        debug: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('register a middleware under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next, exit) => { exit() })

      server.use('/foo', fn)
      server.useAfter('/foo', fn3)
      server.useAfter('/bar', fn3)
      server.use('/bar', fn)
      server.use('/bar', fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn3)
      })
    })

    it('registers multiple middlewares under a specific path', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((req, res, next) => { next() })
      const fn3 = sinon.spy((req, res, next) => { next() })
      const fn4 = sinon.spy((req, res, next, exit) => { exit() })

      server.use('/foo', fn, fn2, fn3, fn4)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn4).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3, fn4)
      })
    })
  })

  describe('route()', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('should register a route in an internal storage', () => {
      server.route('GET', '/foo/:name', (req, res, next, done) => { done() })

      inspect(server.__routes).isObject()
      inspect(server.__routes.size).isEql(1)
      inspect(server.__routes.get('GET /foo/:name')).hasProps({
        method: 'GET',
        route: '/foo/:name',
        keys: [{
          name: 'name',
          offset: 6,
          optional: false
        }]
      })
    })

    it('should add a route', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      server.route('GET', '/foo/:name', fn)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
      })
    })

    it('should add multiple middlewares', () => {
      const fn = sinon.spy((req, res, next, done) => { next() })
      const fn2 = sinon.spy((req, res, next, done) => { next() })
      const fn3 = sinon.spy((req, res, next, done) => { done() })
      server.route('GET', '/foo/bla', fn, fn2, fn3)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasCalledOnce()
        inspect(fn3).wasCalledOnce()
        inspect(fn).hasCallOrder(fn2, fn3)
      })
    })
  })

  describe('errorHandler', () => {
    let server

    beforeEach(() => {
      server = new CoreIO.Server({
        noServer: true
      })

      server.errorLevel = 1
    })

    afterEach(() => {
      server.removeAllRoutes(true)
    })

    it('calls an error handler', () => {
      const fn = sinon.spy((req, res, next) => { throw new Error('Fucking error!') })
      const fn2 = sinon.spy((err, req, res, next) => { next() })
      server.use(fn)
      server.errorHandler(fn2)

      return server.dispatch({
        path: '/foo/bla',
        method: 'GET',
        accepts: () => true
      }, {
        status() {},
        send() {}
      }).then(() => {
        inspect(fn2).wasCalledOnce()
      })
    })

    it.skip('never calls an error handler if no error was thrown', () => {
      const fn = sinon.spy((req, res, next) => { next() })
      const fn2 = sinon.spy((err, req, res, next) => { console.log(err); next() })
      server.use(fn)
      server.errorHandler(fn2)

      return server.dispatch(fakeReq, fakeRes).then(() => {
        inspect(fn).wasCalledOnce()
        inspect(fn2).wasNotCalled()
      })
    })

    erroClassArr.forEach((test) => {
      it(`calls an final error handler if an ${test.ErrorClass.name} was thrown`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass('Beer is empty!') })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name
          })
        })
      })

      it(`return an extended error for ${test.ErrorClass.name} if level is set to 2`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 2

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name,
            error: test.error
          })
        })
      })

      it(`return an extended error with stack trace for ${test.ErrorClass.name} if level is set to 3`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(true)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 3

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(jsonStub).wasCalledOnce()
          inspect(sendStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(jsonStub).wasCalledWith({
            status: test.status,
            message: test.message,
            type: test.name,
            error: test.error,
            stack: sinon.match.string
          })
        })
      })

      it(`calls an final error handler if an ${test.ErrorClass.name} was thrown (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass('Beer is empty!') })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWith(
            `${test.status} ${test.message}`
          )
        })
      })

      it(`return an extended error for ${test.ErrorClass.name} if level is set to 2 (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 2

        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWithMatch(
            `${test.status} ${test.message}\n\n${test.error}`
          )
        })
      })

      it(`return an extended error with stack trace for ${test.ErrorClass.name} if level is set to 3 (text/plain)`, () => {
        const fn = sinon.spy((req, res, next) => { throw new test.ErrorClass(test.error) })
        const fn2 = sinon.spy((err, req, res, next) => { next() })
        const jsonStub = sinon.stub()
        const sendStub = sinon.stub()
        const statusStub = sinon.stub()
        const acceptsStub = sinon.stub()
        acceptsStub.returns(false)

        server.use(fn)
        server.errorHandler(fn2)
        server.errorLevel = 3

        const err = new test.ErrorClass(test.error)
        err.level = 3
        inspect.print(err.toString())
        return server.dispatch({
          path: '/foo/bla',
          method: 'GET',
          accepts: acceptsStub
        }, {
          status: statusStub,
          send: sendStub,
          json: jsonStub
        }).then(() => {
          inspect(fn2).wasCalledOnce()
          inspect(sendStub).wasCalledOnce()
          inspect(jsonStub).wasNotCalled()
          inspect(statusStub).wasCalledOnce()
          inspect(statusStub).wasCalledWith(test.status)
          inspect(sendStub).wasCalledWithMatch(
            `${test.status} ${test.message}\n\n${test.error}\n\nError: ${test.message}`
          )
        })
      })
    })
  })
})
<|endoftext|>


<commit_before>import angular from 'angular';
import 'angular-ui-router';
import 'angular-bootstrap-npm';
import 'angular-toastr';

import services from './services/services.module';
import security from './security/security.module';
import common from './common/common.module';
import config from './config/config.module';
import login from './login/login.module';
import contacts from './contacts/contacts.module';

import '../style/leadscore.less';

const MODULE_NAME = 'leadscore';

angular.module('leadscore', [
  'ui.router',
  'ui.bootstrap',
  'toastr',
  services,
  security,
  common,
  config,
  login,
  contacts
]);

export default MODULE_NAME;
<commit_msg>Fixed dependency<commit_after>import angular from 'angular';
import 'angular-ui-router';
import 'angular-ui-bootstrap';
import 'angular-toastr';

import services from './services/services.module';
import security from './security/security.module';
import common from './common/common.module';
import config from './config/config.module';
import login from './login/login.module';
import contacts from './contacts/contacts.module';

import '../style/leadscore.less';

const MODULE_NAME = 'leadscore';

angular.module('leadscore', [
  'ui.router',
  'ui.bootstrap',
  'toastr',
  services,
  security,
  common,
  config,
  login,
  contacts
]);

export default MODULE_NAME;
<|endoftext|>


<commit_before>/* eslint no-console: 0 */
/* tslint:disable:no-console */
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

import {
  Display,
  Map2D,
  Map2DPanControl,
  Map2DView,
  Map2DViewFrame,
  Map2DViewLayer,
  OrthographicProjection,
  RepeatingPatternLayer,
  TileSet,
} from 'picimo';

const display = new Display(document.getElementById('three-container'), {
  clearColor: 0x0043ff,
  pixelate: true,
});

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x203040);

const camera3d = new THREE.PerspectiveCamera(75, 1, 1, 10000);
camera3d.position.set(0, 200, 350);
camera3d.up.set(0, 1, 0);

let curCamera = camera3d;

const projection = new OrthographicProjection({ pixelZoom: 3, near: .1, far: 1000, distance: 100 });

const controls = new OrbitControls(camera3d);

display.addEventListener('resize', ({width, height}) => {

  projection.update(width, height);

  camera3d.aspect = width / height;
  camera3d.updateProjectionMatrix();

});

// ////////////////////////////////////////////////////

async function init() {

  const map2d = new Map2D();
  scene.add(map2d);

  const ball = await TileSet.load('ball-pattern-rot.png', { basePath: '../assets/' });

  const view = new Map2DView(map2d, 0, 0, projection.width, projection.height, 256, 256);

  view.addLayer(
    new Map2DViewLayer(view,
      map2d.createTileQuadMeshLayer([ball]),
      RepeatingPatternLayer.fromTile(ball, 1),
    ));

  const viewFrame = new Map2DViewFrame(map2d, 0x66ff00, .5);
  map2d.add(viewFrame);

  const panControl = new Map2DPanControl(view, projection, 200);

  // const changeViewSize = (multiplyByScalar) => {
  //   if (view) {
  //     view.width *= multiplyByScalar;
  //     view.height = calcViewHeight(view.width);
  //     const half = min(view.width, view.height) / 2;
  //     camera2d.left = -half;
  //     camera2d.right = half;
  //     camera2d.top = half;
  //     camera2d.bottom = -half;
  //     camera2d.updateProjectionMatrix();
  //   }
  // };

  document.addEventListener('keyup', (event) => {
    const { keyCode } = event;
    switch (keyCode) {
    case 49: // 1
      // @ts-ignore
      curCamera = projection.camera;
      viewFrame.visible = false;
      controls.enabled = false;
      break;
    case 50: // 2
      curCamera = camera3d;
      viewFrame.visible = true;
      controls.enabled = true;
      break;
    case 107: // numPad: add
    case 187: // +
      // changeViewSize(curCamera === camera3d ? 1.1 : 0.9);
      break;
    case 109: // numPad: sub
    case 189: // -
      // @ts-ignore
      // changeViewSize(curCamera === camera2d ? 1.1 : 0.9);
      break;
    }
  });

  display.addEventListener('frame', ({deltaTime: t, display: {renderer}}) => {

    controls.update();

    panControl.update(t);
    view.update();

    renderer.render(scene, curCamera);

  });

};

init();
display.start();
<commit_msg>add center shortcut to example<commit_after>/* eslint no-console: 0 */
/* tslint:disable:no-console */
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

import {
  Display,
  Map2D,
  Map2DPanControl,
  Map2DView,
  Map2DViewFrame,
  Map2DViewLayer,
  OrthographicProjection,
  RepeatingPatternLayer,
  TileSet,
} from 'picimo';

const display = new Display(document.getElementById('three-container'), {
  clearColor: 0x0043ff,
  pixelate: true,
});

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x203040);

const camera3d = new THREE.PerspectiveCamera(75, 1, 1, 10000);
camera3d.position.set(0, 200, 350);
camera3d.up.set(0, 1, 0);

let curCamera = camera3d;

const projection = new OrthographicProjection({ pixelZoom: 3, near: .1, far: 1000, distance: 100 });

const controls = new OrbitControls(camera3d);

display.addEventListener('resize', ({width, height}) => {

  projection.update(width, height);

  camera3d.aspect = width / height;
  camera3d.updateProjectionMatrix();

});

// ////////////////////////////////////////////////////

async function init() {

  const map2d = new Map2D();
  scene.add(map2d);

  const ball = await TileSet.load('ball-pattern-rot.png', { basePath: '../assets/' });

  const view = new Map2DView(map2d, 0, 0, projection.width, projection.height, 256, 256);

  view.addLayer(
    new Map2DViewLayer(view,
      map2d.createTileQuadMeshLayer([ball]),
      RepeatingPatternLayer.fromTile(ball, 1),
    ));

  const viewFrame = new Map2DViewFrame(map2d, 0x66ff00, .5);
  map2d.add(viewFrame);

  const panControl = new Map2DPanControl(view, projection, 200);

  // const changeViewSize = (multiplyByScalar) => {
  //   if (view) {
  //     view.width *= multiplyByScalar;
  //     view.height = calcViewHeight(view.width);
  //     const half = min(view.width, view.height) / 2;
  //     camera2d.left = -half;
  //     camera2d.right = half;
  //     camera2d.top = half;
  //     camera2d.bottom = -half;
  //     camera2d.updateProjectionMatrix();
  //   }
  // };

  document.addEventListener('keyup', (event) => {
    const { keyCode } = event;
    switch (keyCode) {
    case 49: // 1
      // @ts-ignore
      curCamera = projection.camera;
      viewFrame.visible = false;
      controls.enabled = false;
      break;
    case 50: // 2
      curCamera = camera3d;
      viewFrame.visible = true;
      controls.enabled = true;
      break;
    case 67: // c
      controls.target.set(view.centerX, 0, view.centerY);
      break;
    case 107: // numPad: add
    case 187: // +
      // changeViewSize(curCamera === camera3d ? 1.1 : 0.9);
      break;
    case 109: // numPad: sub
    case 189: // -
      // @ts-ignore
      // changeViewSize(curCamera === camera2d ? 1.1 : 0.9);
      break;
    }
  });

  display.addEventListener('frame', ({deltaTime: t, display: {renderer}}) => {

    controls.update();

    panControl.update(t);
    view.update();

    renderer.render(scene, curCamera);

  });

};

init();
display.start();
<|endoftext|>


<commit_before>if(!filters) var filters = {};

filters.drop = function drop(svg, color, opacity){
	// filters go in defs element
	var id = "filter-drop-shadow",
			defs = svg.selectAll("defs").data([id]);
	defs.enter().append("defs");

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// https://gist.github.com/cpbotha/5200394
	// filter chain comes from:
	// https://github.com/wbzyl/d3-notes/blob/master/hello-drop-shadow.html
	// cpbotha added explanatory comments
	// read more about SVG filter effects here: http://www.w3.org/TR/SVG/filters.html	// create filter with id #drop-shadow
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// height=130% so that the shadow is not clipped
	var filter = defs.append("filter")
		.attr("id", function(d){return d})
		.attr({x: "-100%", y: "-100%", "height": "330%", "width": "330%"});

	// SourceAlpha refers to opacity of graphic that this filter will be applied to
	// convolve that with a Gaussian with standard deviation 3 and store result
	// in blur
	filter.append("feGaussianBlur")
		.attr("in", "SourceAlpha")
		.attr("stdDeviation",1)
		.attr("result", "blur");

	// translate output of Gaussian blur to the right and downwards with 2px
	// store result in offsetBlur
	filter.append("feOffset")
		.attr("in", "blur")
		.attr("dx", 2)
		.attr("dy", 2)
		.attr("result", "offsetBlur");

	filter.append("feFlood")
		.attr({"flood-color": color || "steelblue", "flood-opacity": opacity || "1"})
		.attr("result", "offsetColor");
	filter.append("feComposite")
		.attr({"in": "offsetColor", "in2": "offsetBlur", "operator": "in"})
		.attr("result", "offsetBlur");

	// overlay original SourceGraphic over translated blurred opacity by using
	// feMerge filter. Order of specifying inputs is important!
	var feMerge = filter.append("feMerge");

	feMerge.append("feMergeNode")
		.attr("in", "offsetBlur")
	feMerge.append("feMergeNode")
		.attr("in", "SourceGraphic");

	return "url(#" + id + ")"
}

filters.inset = function drop(svg, color, opacity){
	// filters go in defs element
	var id = "filter-inset-shadow",
			defs = svg.selectAll("defs").data([id]);
	defs.enter().append("defs");

	// create filter with id #drop-shadow
	// height=130% so that the shadow is not clipped
	var filter = defs.append("filter")
		.attr("id", id)
		.attr({x: "-50%", y: "-50%", "height": "200%", "width": "200%"});

	// invert the source image
	filter.append("feComponentTransfer")
		.attr("in", "SourceAlpha")
		.append("feFuncA")
		.attr({"type": "table", "tableValues": "1 0"})

	// SourceAlpha refers to opacity of graphic that this filter will be applied to
	// convolve that with a Gaussian
	filter.append("feGaussianBlur")
		.attr({"stdDeviation":3});

	// translate output of Gaussian blur to the right and downwards with 2px
	// store result in offsetBlur
	filter.append("feOffset")
		.attr("dx",5)
		.attr("dy",5)
		.attr("result", "offsetBlur");

	// flood the entire filter box
	filter.append("feFlood")
		.attr({"flood-color": color || "black", "flood-opacity": opacity || ".2"})
		.attr("result", "offsetColor");
	// mask the flood with the offset, inverted blur
	filter.append("feComposite")
		.attr({"in2": "offsetBlur", "operator": "in"});
	// then mask that with the source image
	filter.append("feComposite")
		.attr({"in2": "SourceAlpha", "operator": "in", result: "shadow"});

	// overlay original SourceGraphic over translated blurred opacity by using
	// feMerge filter. Order of specifying inputs is important!
	var feMerge = filter.append("feMerge");

	// merge with the shadow on top
	feMerge.append("feMergeNode")
		.attr("in", "SourceGraphic");
	feMerge.append("feMergeNode")
		.attr("in", "shadow")
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	return "url(#" + id + ")"
}
/**filter.sphere, filter.bubble
 * Copyright (c) 2015, cool.blue@y7mail.com.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the cool.blue@y7mail.com nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

filters.sphere = function (svg, baseColor, opacity, highlightColor) {
	baseColor = baseColor || "black";
	opacity = opacity || 1;
	highlightColor = highlightColor || "white";
	var id = "filter-spherical-shading" + ["", baseColor, highlightColor].join("-"),
			defs = svg.selectAll("defs").data([id]),
			c = tinycolor(baseColor).toHsv(),
			stop1 = tinycolor({h: c.h, s: c.s, v: c.v}),
			stop2 = tinycolor({h: (c.h == 0) ? 0 : (c.h + 60)%360, s: c.s, v: c.v*0.65});

	defs.enter().append("defs");
	var sphere = defs.append("radialGradient")
		.attr({"id": id, "cx": "50%", "cy": "50%", "r": "80%", "fx": "25%", "fy": "25%",});
	sphere.append("stop")
		.attr({"offset": "0", "stop-color": highlightColor || "white"})
	sphere.append("stop")
		.attr({"offset": "0.5", "stop-color": stop1.toHexString(), opacity: opacity})
	sphere.append("stop")
		.attr({"offset": "1", "stop-color": stop2.toHexString(), opacity: 0.75*opacity})
	//sphere.append("stop")
	//		.attr({"offset": "0%", "stop-color": highlightColor || "white"})
	//sphere.append("stop")
	//		.attr({"offset": "75%", "stop-color": baseColor || "black"})
	return ["url(#", id, ")"].join("");
}
filters.bubble = function (svg, baseColor, opacity, highlightColor) {
	baseColor = baseColor || "black";
	opacity = opacity || 0.3;
	highlightColor = highlightColor || "white";
	var id = "filter-bubble-" + baseColor + "-" + highlightColor,
			defs = svg.selectAll("defs").data([id]),
			c = tinycolor(baseColor).toHsv(),
			stop1 = tinycolor({h: c.h, s: 100, v: 1}),
			stop2 = tinycolor({h: (c.h == 0) ? 0 : (c.h + 60)%360, s: 100, v: 0.65});

	defs.enter().append("defs");
	var sphere = defs.selectAll(".bubble").data([baseColor], function(d){return d}).enter()
		.append("radialGradient")
		.attr({"id": id, "cx": "50%", "cy": "50%", "r": "80%", "fx": "25%", "fy": "25%",});
	sphere.append("stop")
		.attr({"offset": "0", "stop-color": highlightColor || "white"})
	sphere.append("stop")
		.attr({"offset": "0.5", "stop-color": stop1.toHexString(), opacity: 0.65*opacity})
	sphere.append("stop")
		.attr({"offset": "1", "stop-color": stop2.toHexString(), opacity: 0.75*opacity})
	return "url(#" + id + ")"
}
filters.cSphere = function(ctx, x, y, radius, baseColor, highlightColor) {
    // Coloured radial gradient in circle shape

    baseColor = baseColor || "black";
    highlightColor = highlightColor || "white";

    var c = tinycolor(baseColor).toHsv(),
        stop1 = tinycolor({h: c.h, s: 255, v: c.v * 0.6}),
        stop2 = tinycolor({
            h: c.h,
            s: c.s,
            v: c.v * 0.01 //0.65
        });

    var startAngle = 0;
    var endAngle = Math.PI * 2;
    var antiClockwise = false;

    var radialGradient = ctx.createRadialGradient(
        -0.5 * radius + x, -0.5 * radius + y,
        .0 * radius,
        x, y, 1.5 * radius
    );
    radialGradient.addColorStop(0, highlightColor);
    radialGradient.addColorStop(0.6, stop1.toHexString());
    radialGradient.addColorStop(0.9, stop2.toHexString());
    radialGradient.addColorStop(1, stop2.toHexString());

    ctx.fillStyle = radialGradient;

    ctx.beginPath();
    ctx.arc(x, y, radius, startAngle, endAngle);
    ctx.closePath();

    ctx.fill();
}
filters.makeSpriteSheet =  function makeSpriteSheet(radius, colors){
    var padding = 2, cell = 2 * radius + padding,
        canvas = d3.select(document.createElement("canvas"))
            .attr({width: cell * colors.length, height: cell})
            .node(),
        context = canvas.getContext('2d'),

        sheet = new PIXI.BaseTexture.fromCanvas(
            colors.reduce(
                function(ctx, c, i) {
                    return (filters.cSphere(ctx, cell * i + cell / 2, cell
                        / 2, radius, c), ctx);
                },
                context).canvas
        );

    return function(index) {
        return new PIXI.Texture(sheet,
            new PIXI.Rectangle(index * cell, 0, cell, canvas.height)
        )
    };
}
<commit_msg>shadow.js - removed d3 dependency<commit_after>if(!filters) var filters = {};

filters.drop = function drop(svg, color, opacity){
	// filters go in defs element
	var id = "filter-drop-shadow",
			defs = svg.selectAll("defs").data([id]);
	defs.enter().append("defs");

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// https://gist.github.com/cpbotha/5200394
	// filter chain comes from:
	// https://github.com/wbzyl/d3-notes/blob/master/hello-drop-shadow.html
	// cpbotha added explanatory comments
	// read more about SVG filter effects here: http://www.w3.org/TR/SVG/filters.html	// create filter with id #drop-shadow
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// height=130% so that the shadow is not clipped
	var filter = defs.append("filter")
		.attr("id", function(d){return d})
		.attr({x: "-100%", y: "-100%", "height": "330%", "width": "330%"});

	// SourceAlpha refers to opacity of graphic that this filter will be applied to
	// convolve that with a Gaussian with standard deviation 3 and store result
	// in blur
	filter.append("feGaussianBlur")
		.attr("in", "SourceAlpha")
		.attr("stdDeviation",1)
		.attr("result", "blur");

	// translate output of Gaussian blur to the right and downwards with 2px
	// store result in offsetBlur
	filter.append("feOffset")
		.attr("in", "blur")
		.attr("dx", 2)
		.attr("dy", 2)
		.attr("result", "offsetBlur");

	filter.append("feFlood")
		.attr({"flood-color": color || "steelblue", "flood-opacity": opacity || "1"})
		.attr("result", "offsetColor");
	filter.append("feComposite")
		.attr({"in": "offsetColor", "in2": "offsetBlur", "operator": "in"})
		.attr("result", "offsetBlur");

	// overlay original SourceGraphic over translated blurred opacity by using
	// feMerge filter. Order of specifying inputs is important!
	var feMerge = filter.append("feMerge");

	feMerge.append("feMergeNode")
		.attr("in", "offsetBlur")
	feMerge.append("feMergeNode")
		.attr("in", "SourceGraphic");

	return "url(#" + id + ")"
}

filters.inset = function drop(svg, color, opacity){
	// filters go in defs element
	var id = "filter-inset-shadow",
			defs = svg.selectAll("defs").data([id]);
	defs.enter().append("defs");

	// create filter with id #drop-shadow
	// height=130% so that the shadow is not clipped
	var filter = defs.append("filter")
		.attr("id", id)
		.attr({x: "-50%", y: "-50%", "height": "200%", "width": "200%"});

	// invert the source image
	filter.append("feComponentTransfer")
		.attr("in", "SourceAlpha")
		.append("feFuncA")
		.attr({"type": "table", "tableValues": "1 0"})

	// SourceAlpha refers to opacity of graphic that this filter will be applied to
	// convolve that with a Gaussian
	filter.append("feGaussianBlur")
		.attr({"stdDeviation":3});

	// translate output of Gaussian blur to the right and downwards with 2px
	// store result in offsetBlur
	filter.append("feOffset")
		.attr("dx",5)
		.attr("dy",5)
		.attr("result", "offsetBlur");

	// flood the entire filter box
	filter.append("feFlood")
		.attr({"flood-color": color || "black", "flood-opacity": opacity || ".2"})
		.attr("result", "offsetColor");
	// mask the flood with the offset, inverted blur
	filter.append("feComposite")
		.attr({"in2": "offsetBlur", "operator": "in"});
	// then mask that with the source image
	filter.append("feComposite")
		.attr({"in2": "SourceAlpha", "operator": "in", result: "shadow"});

	// overlay original SourceGraphic over translated blurred opacity by using
	// feMerge filter. Order of specifying inputs is important!
	var feMerge = filter.append("feMerge");

	// merge with the shadow on top
	feMerge.append("feMergeNode")
		.attr("in", "SourceGraphic");
	feMerge.append("feMergeNode")
		.attr("in", "shadow")
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	return "url(#" + id + ")"
}
/**filter.sphere, filter.bubble
 * Copyright (c) 2015, cool.blue@y7mail.com.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the cool.blue@y7mail.com nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

filters.sphere = function (svg, baseColor, opacity, highlightColor) {
	baseColor = baseColor || "black";
	opacity = opacity || 1;
	highlightColor = highlightColor || "white";
	var id = "filter-spherical-shading" + ["", baseColor, highlightColor].join("-"),
			defs = svg.selectAll("defs").data([id]),
			c = tinycolor(baseColor).toHsv(),
			stop1 = tinycolor({h: c.h, s: c.s, v: c.v}),
			stop2 = tinycolor({h: (c.h == 0) ? 0 : (c.h + 60)%360, s: c.s, v: c.v*0.65});

	defs.enter().append("defs");
	var sphere = defs.append("radialGradient")
		.attr({"id": id, "cx": "50%", "cy": "50%", "r": "80%", "fx": "25%", "fy": "25%",});
	sphere.append("stop")
		.attr({"offset": "0", "stop-color": highlightColor || "white"})
	sphere.append("stop")
		.attr({"offset": "0.5", "stop-color": stop1.toHexString(), opacity: opacity})
	sphere.append("stop")
		.attr({"offset": "1", "stop-color": stop2.toHexString(), opacity: 0.75*opacity})
	//sphere.append("stop")
	//		.attr({"offset": "0%", "stop-color": highlightColor || "white"})
	//sphere.append("stop")
	//		.attr({"offset": "75%", "stop-color": baseColor || "black"})
	return ["url(#", id, ")"].join("");
}
filters.bubble = function (svg, baseColor, opacity, highlightColor) {
	baseColor = baseColor || "black";
	opacity = opacity || 0.3;
	highlightColor = highlightColor || "white";
	var id = "filter-bubble-" + baseColor + "-" + highlightColor,
			defs = svg.selectAll("defs").data([id]),
			c = tinycolor(baseColor).toHsv(),
			stop1 = tinycolor({h: c.h, s: 100, v: 1}),
			stop2 = tinycolor({h: (c.h == 0) ? 0 : (c.h + 60)%360, s: 100, v: 0.65});

	defs.enter().append("defs");
	var sphere = defs.selectAll(".bubble").data([baseColor], function(d){return d}).enter()
		.append("radialGradient")
		.attr({"id": id, "cx": "50%", "cy": "50%", "r": "80%", "fx": "25%", "fy": "25%",});
	sphere.append("stop")
		.attr({"offset": "0", "stop-color": highlightColor || "white"})
	sphere.append("stop")
		.attr({"offset": "0.5", "stop-color": stop1.toHexString(), opacity: 0.65*opacity})
	sphere.append("stop")
		.attr({"offset": "1", "stop-color": stop2.toHexString(), opacity: 0.75*opacity})
	return "url(#" + id + ")"
}
filters.cSphere = function(ctx, x, y, radius, baseColor, highlightColor) {
    // Coloured radial gradient in circle shape

    baseColor = baseColor || "black";
    highlightColor = highlightColor || "white";

    var c = tinycolor(baseColor).toHsv(),
        stop1 = tinycolor({h: c.h, s: 255, v: c.v * 0.6}),
        stop2 = tinycolor({
            h: c.h,
            s: c.s,
            v: c.v * 0.01 //0.65
        });

    var startAngle = 0;
    var endAngle = Math.PI * 2;
    var antiClockwise = false;

    var radialGradient = ctx.createRadialGradient(
        -0.5 * radius + x, -0.5 * radius + y,
        .0 * radius,
        x, y, 1.5 * radius
    );
    radialGradient.addColorStop(0, highlightColor);
    radialGradient.addColorStop(0.6, stop1.toHexString());
    radialGradient.addColorStop(0.9, stop2.toHexString());
    radialGradient.addColorStop(1, stop2.toHexString());

    ctx.fillStyle = radialGradient;

    ctx.beginPath();
    ctx.arc(x, y, radius, startAngle, endAngle);
    ctx.closePath();

    ctx.fill();
}
filters.makeSpriteSheet =  function makeSpriteSheet(radius, colors){
    var padding = 2, cell = 2 * radius + padding,
        canvas = document.createElement("canvas"),
        context = canvas.getContext('2d');
    canvas.width = cell * colors.length;
    canvas.height = cell;

    var sheet = new PIXI.BaseTexture.fromCanvas(
            colors.reduce(
                function(ctx, c, i) {
                    return (filters.cSphere(ctx, cell * i + cell / 2, cell
                        / 2, radius, c), ctx);
                },
                context).canvas
        );

    return function(index) {
        return new PIXI.Texture(sheet,
            new PIXI.Rectangle(index * cell, 0, cell, canvas.height)
        )
    };
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2013. Telecom ParisTech/TSI/MM/GPAC Cyril Concolato
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * This notice must stay in all subsequent versions of this code.
 */
 function MP4Box() {
	this.log_level = this.LOG_LEVEL_INFO;

	this.sampleListBuilt = false;
	this.inputStream = null;
	this.inputIsoFile = null;
	this.onReady = null;
	this.readySent = false;
	this.onSegment = null;
	this.onError = null;

	this.fragmentedTracks = new Array();
	this.isFragmentationStarted = false;
	this.nextMoofNumber = 0;
}

MP4Box.prototype.LOG_LEVEL_ERROR 	= 4;
MP4Box.prototype.LOG_LEVEL_WARNING 	= 3;
MP4Box.prototype.LOG_LEVEL_INFO 	= 2;
MP4Box.prototype.LOG_LEVEL_DEBUG 	= 1;

MP4Box.prototype.log = function(level, msg) {
	if (level >= this.log_level) {
		console.log("[MP4Box] "+msg);
	}
}

MP4Box.prototype.setSegmentOptions = function(id, user, options) {
	var trak = this.inputIsoFile.getTrackById(id);
	if (trak) {
		var fragTrack = {};
		this.fragmentedTracks.push(fragTrack);
		fragTrack.id = id;
		fragTrack.user = user;
		fragTrack.nextSample = 0;
		fragTrack.stream = null;
		fragTrack.nb_samples = 1000;
		fragTrack.rapAlignement = true;
		if (options) {
			if (options.nb_samples != undefined) fragTrack.nb_samples = options.nbSamples;
			if (options.rapAlignement != undefined) fragTrack.rapAlignement = options.rapAlignement;
		}
	}
}

MP4Box.prototype.unsetSegmentOptions = function(id) {
	var index = -1;
	for (var i = 0; i < this.fragmentedTracks.length; i++) {
		var fragTrack = this.fragmentedTracks[i];
		if (fragTrack.id == id) {
			index = i;
		}
	}
	if (index > -1) {
		this.fragmentedTracks.splice(index, 1);
	}
}

MP4Box.prototype.createSingleSampleMoof = function(sample) {
	var moof = new BoxParser.moofBox();
	var mfhd = new BoxParser.mfhdBox();
	mfhd.sequence_number = this.nextMoofNumber;
	this.nextMoofNumber++;
	moof.boxes.push(mfhd);
	var traf = new BoxParser.trafBox();
	moof.boxes.push(traf);
	var tfhd = new BoxParser.tfhdBox();
	traf.boxes.push(tfhd);
	tfhd.track_ID = sample.track_id;
	tfhd.flags = BoxParser.TFHD_FLAG_DEFAULT_BASE_IS_MOOF;
	var tfdt = new BoxParser.tfdtBox();
	traf.boxes.push(tfdt);
	tfdt.baseMediaDecodeTime = sample.dts;
	var trun = new BoxParser.trunBox();
	traf.boxes.push(trun);
	moof.trun = trun;
	trun.flags = BoxParser.TRUN_FLAGS_DATA_OFFSET | BoxParser.TRUN_FLAGS_DURATION |
				 BoxParser.TRUN_FLAGS_SIZE | BoxParser.TRUN_FLAGS_FLAGS |
				 BoxParser.TRUN_FLAGS_CTS_OFFSET;
	trun.data_offset = 0;
	trun.first_sample_flags = 0;
	trun.sample_count = 1;
	trun.sample_duration = new Array();
	trun.sample_duration[0] = sample.duration;
	trun.sample_size = new Array();
	trun.sample_size[0] = sample.size;
	trun.sample_flags = new Array();
	trun.sample_flags[0] = 0;
	trun.sample_composition_time_offset = new Array();
	trun.sample_composition_time_offset[0] = sample.cts - sample.dts;
	return moof;
}

MP4Box.prototype.createFragment = function(input, track_id, sampleNumber, stream_) {
	var trak = this.inputIsoFile.getTrackById(track_id);
	var sample = trak.samples[sampleNumber];

	if (this.inputStream.byteLength < sample.offset + sample.size) {
		return null;
	}

	var stream = stream_ || new DataStream();
	stream.endianness = DataStream.BIG_ENDIAN;

	var moof = this.createSingleSampleMoof(sample);
	moof.write(stream);

	/* adjusting the data_offset now that the moof size is known*/
	moof.trun.data_offset = moof.size+8; //8 is mdat header
	this.log(MP4Box.LOG_LEVEL_DEBUG, "Adjusting data_offset with new value "+moof.trun.data_offset);
	stream.adjustUint32(moof.trun.data_offset_position, moof.trun.data_offset);

	var mdat = new BoxParser.mdatBox();
	mdat.data = new ArrayBuffer();
	this.inputStream.seek(sample.offset);
	mdat.data = this.inputStream.readUint8Array(sample.size);
	mdat.write(stream);
	return stream;
}

MP4Box.prototype.open = function(ab) {
	var concatenateBuffers = function(buffer1, buffer2) {
	  var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
	  tmp.set(new Uint8Array(buffer1), 0);
	  tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
	  return tmp.buffer;
	};

	var stream;

	if (!this.inputStream) {
		this.inputStream = new DataStream(ab, 0, DataStream.BIG_ENDIAN);
	} else {
		this.inputStream.buffer = concatenateBuffers(this.inputStream.buffer, ab);
	}
	if (!this.inputIsoFile) {
		this.inputIsoFile = new ISOFile();
	}
	if (!this.inputIsoFile.moov) {
		this.inputIsoFile.parse(this.inputStream);
	}
	if (!this.inputIsoFile.moov) {
		return false;
	} else {
		if (!this.sampleListBuilt) {
			this.inputIsoFile.buildSampleLists();
			this.sampleListBuilt = true;
		}
		if (this.onReady && !this.readySent) {
			var info = this.getInfo();
			this.readySent = true;
			this.onReady(info);
		}
		return true;
	}
}

MP4Box.prototype.processFragments = function() {
	if (this.isFragmentationStarted) {
		for (var i = 0; i < this.fragmentedTracks.length; i++) {
			var fragTrak = this.fragmentedTracks[i];
			var trak = this.inputIsoFile.getTrackById(fragTrak.id);
//			for (var j = this.fragmentedTracks[i].nextSample; j < 50; j++) {
			while (fragTrak.nextSample < trak.samples.length) {
				this.log(MP4Box.LOG_LEVEL_INFO, "Creating media fragment on track #"+fragTrak.id
												+" for sample "+fragTrak.nextSample);
				var result = this.createFragment(this.inputIsoFile, fragTrak.id, fragTrak.nextSample, fragTrak.stream);
				if (result) {
					fragTrak.stream = result;
					fragTrak.nextSample++;
				} else {
					return;
				}
				if (this.onSegment &&
					(fragTrak.nextSample % fragTrak.nb_samples == 0 || fragTrak.nextSample >= trak.samples.length)) {
					this.log(MP4Box.LOG_LEVEL_INFO, "Sending fragmented data on track #"+fragTrak.id+" for sample "+fragTrak.nextSample);
					this.onSegment(fragTrak.id, fragTrak.user, fragTrak.stream.buffer);
					/* force the creation of a new buffer */
					fragTrak.stream = null;
				}
			}
		}
	}
}

MP4Box.prototype.appendBuffer = function(ab) {
	var stream;
	var is_open = this.open(ab);
	if (!is_open) return;
	this.processFragments();
}

MP4Box.prototype.getInfo = function() {
	var movie = {};
	movie.duration = this.inputIsoFile.moov.mvhd.duration;
	movie.timescale = this.inputIsoFile.moov.mvhd.timescale;
	movie.isFragmented = (this.inputIsoFile.moov.mvex != null);
	if (movie.isFragmented) {
		movie.fragment_duration = this.inputIsoFile.moov.mvex.mehd.fragment_duration;
	}
	movie.isProgressive = this.inputIsoFile.isProgressive;
	movie.hasIOD = (this.inputIsoFile.moov.iods != null);
	movie.brands = [];
	movie.brands.push(this.inputIsoFile.ftyp.major_brand);
	movie.brands.join(this.inputIsoFile.ftyp.compatible_brands);
	var _1904 = (new Date(4, 0, 1, 0, 0, 0, 0).getTime());
	movie.created = new Date(_1904+this.inputIsoFile.moov.mvhd.creation_time*1000);
	movie.modified = new Date(_1904+this.inputIsoFile.moov.mvhd.modification_time*1000);
	movie.tracks = new Array();
	for (i = 0; i < this.inputIsoFile.moov.traks.length; i++) {
		var trak = this.inputIsoFile.moov.traks[i];
		var sample_desc = trak.mdia.minf.stbl.stsd.entries[0];
		var track = {};
		movie.tracks.push(track);
		track.id = trak.tkhd.track_id;
		track.created = new Date(_1904+trak.tkhd.creation_time*1000);
		track.modified = new Date(_1904+trak.tkhd.modification_time*1000);
		track.movie_duration = trak.tkhd.duration;
		track.layer = trak.tkhd.layer;
		track.alternate_group = trak.tkhd.alternate_group;
		track.volume = trak.tkhd.volume;
		track.matrix = trak.tkhd.matrix;
		track.track_width = trak.tkhd.width/(1<<16);
		track.track_height = trak.tkhd.height/(1<<16);
		track.timescale = trak.mdia.mdhd.timescale;
		track.duration = trak.mdia.mdhd.duration;
		track.codec = sample_desc.getCodec();
		track.video = {};
		track.video.width = sample_desc.getWidth();
		track.video.height = sample_desc.getHeight();
		track.audio = {};
		track.audio.sample_rate = sample_desc.getSampleRate();
		track.audio.channel_count = sample_desc.getChannelCount();
		track.audio.sample_size = sample_desc.getSampleSize();
		track.language = trak.mdia.mdhd.languageString;
		track.nb_samples = trak.samples.length;
	}
	return movie;
}

MP4Box.prototype.getInitializationSegment = function() {
	var stream = new DataStream();
	stream.endianness = DataStream.BIG_ENDIAN;
	this.inputIsoFile.writeInitializationSegment(stream);
	return stream.buffer;
}

MP4Box.prototype.initializeSegmentation = function() {
	if (!this.isFragmentationStarted) {
		this.isFragmentationStarted = true;
		this.nextMoofNumber = 0;
		this.inputIsoFile.resetTables();
	}
	var initSegs = new Array();
	for (var i = 0; i < this.fragmentedTracks.length; i++) {
		for (var j = 0; j < this.inputIsoFile.moov.boxes.length; j++) {
			var box = this.inputIsoFile.moov.boxes[j];
			if (box.type == "trak") {
				this.inputIsoFile.moov.boxes[j] = null;
			}
		}
		var trak = this.inputIsoFile.getTrackById(this.fragmentedTracks[i].id);
		for (var j = 0; j < this.inputIsoFile.moov.boxes.length; j++) {
			var box = this.inputIsoFile.moov.boxes[j];
			if (box == null) {
				this.inputIsoFile.moov.boxes[j] = trak;
			}
		}
		seg = {};
		seg.id = trak.tkhd.track_id;
		seg.user = this.fragmentedTracks[i].user;
		seg.buffer = this.getInitializationSegment();
		initSegs.push(seg);
	}
	return initSegs;
}

MP4Box.prototype.flush = function() {
	this.log(MP4Box.LOG_LEVEL_INFO, "Flushing remaining samples");
	this.processFragments();
}<commit_msg>fix for brand concatenation<commit_after>/*
 * Copyright (c) 2012-2013. Telecom ParisTech/TSI/MM/GPAC Cyril Concolato
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * This notice must stay in all subsequent versions of this code.
 */
 function MP4Box() {
	this.log_level = this.LOG_LEVEL_DEBUG;

	this.sampleListBuilt = false;
	this.inputStream = null;
	this.inputIsoFile = null;
	this.onReady = null;
	this.readySent = false;
	this.onSegment = null;
	this.onError = null;

	this.fragmentedTracks = new Array();
	this.isFragmentationStarted = false;
	this.nextMoofNumber = 0;
}

MP4Box.prototype.LOG_LEVEL_ERROR 	= 4;
MP4Box.prototype.LOG_LEVEL_WARNING 	= 3;
MP4Box.prototype.LOG_LEVEL_INFO 	= 2;
MP4Box.prototype.LOG_LEVEL_DEBUG 	= 1;

MP4Box.prototype.log = function(level, msg) {
	if (level >= this.log_level) {
		console.log("[MP4Box] "+msg);
	}
}

MP4Box.prototype.setSegmentOptions = function(id, user, options) {
	var trak = this.inputIsoFile.getTrackById(id);
	if (trak) {
		var fragTrack = {};
		this.fragmentedTracks.push(fragTrack);
		fragTrack.id = id;
		fragTrack.user = user;
		fragTrack.nextSample = 0;
		fragTrack.stream = null;
		fragTrack.nb_samples = 1000;
		fragTrack.rapAlignement = true;
		if (options) {
			if (options.nb_samples != undefined) fragTrack.nb_samples = options.nbSamples;
			if (options.rapAlignement != undefined) fragTrack.rapAlignement = options.rapAlignement;
		}
	}
}

MP4Box.prototype.unsetSegmentOptions = function(id) {
	var index = -1;
	for (var i = 0; i < this.fragmentedTracks.length; i++) {
		var fragTrack = this.fragmentedTracks[i];
		if (fragTrack.id == id) {
			index = i;
		}
	}
	if (index > -1) {
		this.fragmentedTracks.splice(index, 1);
	}
}

MP4Box.prototype.createSingleSampleMoof = function(sample) {
	var moof = new BoxParser.moofBox();
	var mfhd = new BoxParser.mfhdBox();
	mfhd.sequence_number = this.nextMoofNumber;
	this.nextMoofNumber++;
	moof.boxes.push(mfhd);
	var traf = new BoxParser.trafBox();
	moof.boxes.push(traf);
	var tfhd = new BoxParser.tfhdBox();
	traf.boxes.push(tfhd);
	tfhd.track_ID = sample.track_id;
	tfhd.flags = BoxParser.TFHD_FLAG_DEFAULT_BASE_IS_MOOF;
	var tfdt = new BoxParser.tfdtBox();
	traf.boxes.push(tfdt);
	tfdt.baseMediaDecodeTime = sample.dts;
	var trun = new BoxParser.trunBox();
	traf.boxes.push(trun);
	moof.trun = trun;
	trun.flags = BoxParser.TRUN_FLAGS_DATA_OFFSET | BoxParser.TRUN_FLAGS_DURATION |
				 BoxParser.TRUN_FLAGS_SIZE | BoxParser.TRUN_FLAGS_FLAGS |
				 BoxParser.TRUN_FLAGS_CTS_OFFSET;
	trun.data_offset = 0;
	trun.first_sample_flags = 0;
	trun.sample_count = 1;
	trun.sample_duration = new Array();
	trun.sample_duration[0] = sample.duration;
	trun.sample_size = new Array();
	trun.sample_size[0] = sample.size;
	trun.sample_flags = new Array();
	trun.sample_flags[0] = 0;
	trun.sample_composition_time_offset = new Array();
	trun.sample_composition_time_offset[0] = sample.cts - sample.dts;
	return moof;
}

MP4Box.prototype.createFragment = function(input, track_id, sampleNumber, stream_) {
	var trak = this.inputIsoFile.getTrackById(track_id);
	var sample = trak.samples[sampleNumber];

	if (this.inputStream.byteLength < sample.offset + sample.size) {
		return null;
	}

	var stream = stream_ || new DataStream();
	stream.endianness = DataStream.BIG_ENDIAN;

	var moof = this.createSingleSampleMoof(sample);
	moof.write(stream);

	/* adjusting the data_offset now that the moof size is known*/
	moof.trun.data_offset = moof.size+8; //8 is mdat header
	this.log(MP4Box.LOG_LEVEL_DEBUG, "Adjusting data_offset with new value "+moof.trun.data_offset);
	stream.adjustUint32(moof.trun.data_offset_position, moof.trun.data_offset);

	var mdat = new BoxParser.mdatBox();
	mdat.data = new ArrayBuffer();
	this.inputStream.seek(sample.offset);
	mdat.data = this.inputStream.readUint8Array(sample.size);
	mdat.write(stream);
	return stream;
}

MP4Box.prototype.open = function(ab) {
	var concatenateBuffers = function(buffer1, buffer2) {
	  var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
	  tmp.set(new Uint8Array(buffer1), 0);
	  tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
	  return tmp.buffer;
	};

	var stream;

	if (!this.inputStream) {
		this.inputStream = new DataStream(ab, 0, DataStream.BIG_ENDIAN);
	} else {
		this.inputStream.buffer = concatenateBuffers(this.inputStream.buffer, ab);
	}
	if (!this.inputIsoFile) {
		this.inputIsoFile = new ISOFile();
	}
	if (!this.inputIsoFile.moov) {
		this.inputIsoFile.parse(this.inputStream);
	}
	if (!this.inputIsoFile.moov) {
		return false;
	} else {
		if (!this.sampleListBuilt) {
			this.inputIsoFile.buildSampleLists();
			this.sampleListBuilt = true;
		}
		if (this.onReady && !this.readySent) {
			var info = this.getInfo();
			this.readySent = true;
			this.onReady(info);
		}
		return true;
	}
}

MP4Box.prototype.processFragments = function() {
	if (this.isFragmentationStarted) {
		for (var i = 0; i < this.fragmentedTracks.length; i++) {
			var fragTrak = this.fragmentedTracks[i];
			var trak = this.inputIsoFile.getTrackById(fragTrak.id);
//			for (var j = this.fragmentedTracks[i].nextSample; j < 50; j++) {
			while (fragTrak.nextSample < trak.samples.length) {
				this.log(MP4Box.LOG_LEVEL_INFO, "Creating media fragment on track #"+fragTrak.id
												+" for sample "+fragTrak.nextSample);
				var result = this.createFragment(this.inputIsoFile, fragTrak.id, fragTrak.nextSample, fragTrak.stream);
				if (result) {
					fragTrak.stream = result;
					fragTrak.nextSample++;
				} else {
					return;
				}
				if (this.onSegment &&
					(fragTrak.nextSample % fragTrak.nb_samples == 0 || fragTrak.nextSample >= trak.samples.length)) {
					this.log(MP4Box.LOG_LEVEL_INFO, "Sending fragmented data on track #"+fragTrak.id+" for sample "+fragTrak.nextSample);
					this.onSegment(fragTrak.id, fragTrak.user, fragTrak.stream.buffer);
					/* force the creation of a new buffer */
					fragTrak.stream = null;
				}
			}
		}
	}
}

MP4Box.prototype.appendBuffer = function(ab) {
	var stream;
	var is_open = this.open(ab);
	if (!is_open) return;
	this.processFragments();
}

MP4Box.prototype.getInfo = function() {
	var movie = {};
	movie.duration = this.inputIsoFile.moov.mvhd.duration;
	movie.timescale = this.inputIsoFile.moov.mvhd.timescale;
	movie.isFragmented = (this.inputIsoFile.moov.mvex != null);
	if (movie.isFragmented) {
		movie.fragment_duration = this.inputIsoFile.moov.mvex.mehd.fragment_duration;
	}
	movie.isProgressive = this.inputIsoFile.isProgressive;
	movie.hasIOD = (this.inputIsoFile.moov.iods != null);
	movie.brands = [];
	movie.brands.push(this.inputIsoFile.ftyp.major_brand);
	movie.brands = movie.brands.concat(this.inputIsoFile.ftyp.compatible_brands);
	var _1904 = (new Date(4, 0, 1, 0, 0, 0, 0).getTime());
	movie.created = new Date(_1904+this.inputIsoFile.moov.mvhd.creation_time*1000);
	movie.modified = new Date(_1904+this.inputIsoFile.moov.mvhd.modification_time*1000);
	movie.tracks = new Array();
	for (i = 0; i < this.inputIsoFile.moov.traks.length; i++) {
		var trak = this.inputIsoFile.moov.traks[i];
		var sample_desc = trak.mdia.minf.stbl.stsd.entries[0];
		var track = {};
		movie.tracks.push(track);
		track.id = trak.tkhd.track_id;
		track.created = new Date(_1904+trak.tkhd.creation_time*1000);
		track.modified = new Date(_1904+trak.tkhd.modification_time*1000);
		track.movie_duration = trak.tkhd.duration;
		track.layer = trak.tkhd.layer;
		track.alternate_group = trak.tkhd.alternate_group;
		track.volume = trak.tkhd.volume;
		track.matrix = trak.tkhd.matrix;
		track.track_width = trak.tkhd.width/(1<<16);
		track.track_height = trak.tkhd.height/(1<<16);
		track.timescale = trak.mdia.mdhd.timescale;
		track.duration = trak.mdia.mdhd.duration;
		track.codec = sample_desc.getCodec();
		track.video = {};
		track.video.width = sample_desc.getWidth();
		track.video.height = sample_desc.getHeight();
		track.audio = {};
		track.audio.sample_rate = sample_desc.getSampleRate();
		track.audio.channel_count = sample_desc.getChannelCount();
		track.audio.sample_size = sample_desc.getSampleSize();
		track.language = trak.mdia.mdhd.languageString;
		track.nb_samples = trak.samples.length;
	}
	return movie;
}

MP4Box.prototype.getInitializationSegment = function() {
	var stream = new DataStream();
	stream.endianness = DataStream.BIG_ENDIAN;
	this.inputIsoFile.writeInitializationSegment(stream);
	return stream.buffer;
}

MP4Box.prototype.initializeSegmentation = function() {
	if (!this.isFragmentationStarted) {
		this.isFragmentationStarted = true;
		this.nextMoofNumber = 0;
		this.inputIsoFile.resetTables();
	}
	var initSegs = new Array();
	for (var i = 0; i < this.fragmentedTracks.length; i++) {
		for (var j = 0; j < this.inputIsoFile.moov.boxes.length; j++) {
			var box = this.inputIsoFile.moov.boxes[j];
			if (box.type == "trak") {
				this.inputIsoFile.moov.boxes[j] = null;
			}
		}
		var trak = this.inputIsoFile.getTrackById(this.fragmentedTracks[i].id);
		for (var j = 0; j < this.inputIsoFile.moov.boxes.length; j++) {
			var box = this.inputIsoFile.moov.boxes[j];
			if (box == null) {
				this.inputIsoFile.moov.boxes[j] = trak;
			}
		}
		seg = {};
		seg.id = trak.tkhd.track_id;
		seg.user = this.fragmentedTracks[i].user;
		seg.buffer = this.getInitializationSegment();
		initSegs.push(seg);
	}
	return initSegs;
}

MP4Box.prototype.flush = function() {
	this.log(MP4Box.LOG_LEVEL_INFO, "Flushing remaining samples");
	this.processFragments();
}<|endoftext|>