<commit_before>/* global beforeEach describe expect it */
const VirtualAudioGraph = require('../../dist/index.js');
const pingPongDelayParamsFactory = require('../tools/pingPongDelayParamsFactory');
const sineOscFactory = require('../tools/sineOscFactory');

describe('virtualAudioGraph.update - expected behaviour', function () {
  var audioContext;
  var virtualAudioGraph;

  beforeEach(function () {
    audioContext = new AudioContext();
    virtualAudioGraph = new VirtualAudioGraph({
      audioContext: audioContext,
      output: audioContext.destination,
    });
  });

  it('returns itself', function () {
    const virtualNodeParams = [{
      id: 0,
      node: 'oscillator',
      params: {
        type: 'square',
      },
      output: 'output',
    }];
    expect(virtualAudioGraph.update(virtualNodeParams)).toBe(virtualAudioGraph);
  });

  it('adds then removes nodes', function () {
    virtualAudioGraph.update({
      0: {
        node: 'gain',
        output: 'output',
      },
      1: {
        node: 'oscillator',
        output: 0,
      },
    });
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 1,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
    virtualAudioGraph.update({});
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [],
    });
  });

  it('handles random strings for ids', function () {
    virtualAudioGraph.update({
      foo: {
        node: 'gain',
        output: 'output',
      },
      bar: {
        node: 'oscillator',
        output: 'foo',
      },
    });
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 1,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
    virtualAudioGraph.update({});
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [],
    });
  });

  it('changes the node if passed params with same id but different node property', function () {
    virtualAudioGraph.update({
      0: {
        node: 'gain',
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'GainNode',
          gain: {
            value: 1,
            inputs: [],
          },
          inputs: [],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        },
      ],
    });

    virtualAudioGraph.defineNode(pingPongDelayParamsFactory, 'pingPongDelay');

    virtualAudioGraph.update([{
      id: 0,
      node: 'pingPongDelay',
      output: 'output',
    }]);
    /* eslint-disable */
    expect(audioContext.toJSON()).toEqual({ name: 'AudioDestinationNode', inputs: [ Object({ name: 'OscillatorNode', type: 'sine', frequency: Object({ value: 440, inputs: [  ] }), detune: Object({ value: 0, inputs: [  ] }), inputs: [  ] }), Object({ name: 'StereoPannerNode', pan: Object({ value: 1, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ '<circular:DelayNode>' ] }) ] }) ] }) ] }) ] }), Object({ name: 'StereoPannerNode', pan: Object({ value: -1, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ '<circular:DelayNode>' ] }) ] }) ] }) ] }) ] }) ] });
    /* eslint-enable */
  });

  it('updates standard and custom nodes if passed same id but different params', function () {
    virtualAudioGraph.update({
      0: {
        node: 'oscillator',
        params: {
          frequency: 220,
          detune: -9,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'OscillatorNode',
        type: 'sine',
        frequency: {
          value: 220,
          inputs: [],
        },
        detune: {
          value: -9,
          inputs: [],
        },
        inputs: [],
      }],
    });

    virtualAudioGraph.update({
      0: {
        node: 'oscillator',
        params: {
          frequency: 880,
          detune: 0,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'OscillatorNode',
        type: 'sine',
        frequency: {
          value: 880,
          inputs: [],
        },
        detune: {
          value: 0,
          inputs: [],
        },
        inputs: [],
      }],
    });

    virtualAudioGraph.defineNode(sineOscFactory, 'sineOscFactory');

    virtualAudioGraph.update({
      0: {
        node: 'sineOscFactory',
        params: {
          frequency: 110,
          gain: 0.5,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 0.5,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 110,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });

    virtualAudioGraph.update({
      0: {
        node: 'sineOscFactory',
        params: {
          frequency: 660,
          gain: 0.2,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 0.2,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 660,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
  });

  it('connects nodes to each other', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    }]);
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'GainNode',
          gain: {
            value: 1,
            inputs: [],
          },
          inputs: [
            {
              name: 'OscillatorNode',
              type: 'sine',
              frequency: {
                value: 440,
                inputs: [],
              },
              detune: {
                value: 0,
                inputs: [],
              },
              inputs: [],
            },
          ],
        },
      ],
    });
    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          inputs: [],
        },
      ],
    });
  });

  it('reconnects nodes to each other', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    }]);
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [],
              },
              'detune': {
                'value': 0,
                'inputs': [],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [],
        },
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          'inputs': [],
        },
      ],
    });
  });

  it('connects and reconnects nodes to audioParams', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    },
    {
      id: 2,
      node: 'oscillator',
      output: {id: 1, destination: 'frequency'},
      params: {
        frequency: 0.5,
        type: 'triangle',
      },
    }]);

    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [
                  {
                    'name': 'OscillatorNode',
                    'type': 'triangle',
                    'frequency': {
                      'value': 0.5,
                      'inputs': [],
                    },
                    'detune': {
                      'value': 0,
                      'inputs': [],
                    },
                    'inputs': [],
                  },
                ],
              },
              'detune': {
                'value': 0,
                'inputs': [],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    },
    {
      id: 2,
      node: 'oscillator',
      output: [
        {
          id: 1,
          destination: 'detune',
        },
      ],
      params: {
        frequency: 0.5,
        type: 'triangle',
      },
    }]);

    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [],
              },
              'detune': {
                'value': 0,
                'inputs': [
                  {
                    'name': 'OscillatorNode',
                    'type': 'triangle',
                    'frequency': {
                      'value': 0.5,
                      'inputs': [],
                    },
                    'detune': {
                      'value': 0,
                      'inputs': [],
                    },
                    'inputs': [],
                  },
                ],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          'inputs': [],
        },
      ],
    });
  });
});
<commit_msg>update spec<commit_after>/* global beforeEach describe expect it */
const VirtualAudioGraph = require('../../dist/index.js');
const pingPongDelayParamsFactory = require('../tools/pingPongDelayParamsFactory');
const sineOscFactory = require('../tools/sineOscFactory');

describe('virtualAudioGraph.update - expected behaviour', function () {
  var audioContext;
  var virtualAudioGraph;

  beforeEach(function () {
    audioContext = new AudioContext();
    virtualAudioGraph = new VirtualAudioGraph({
      audioContext: audioContext,
      output: audioContext.destination,
    });
  });

  it('returns itself', function () {
    const virtualNodeParams = [{
      id: 0,
      node: 'oscillator',
      params: {
        type: 'square',
      },
      output: 'output',
    }];
    expect(virtualAudioGraph.update(virtualNodeParams)).toBe(virtualAudioGraph);
  });

  it('adds then removes nodes', function () {
    virtualAudioGraph.update({
      0: {
        node: 'gain',
        output: 'output',
      },
      1: {
        node: 'oscillator',
        output: 0,
      },
    });
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 1,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
    virtualAudioGraph.update({});
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [],
    });
  });

  it('handles random strings for ids', function () {
    virtualAudioGraph.update({
      foo: {
        node: 'gain',
        output: 'output',
      },
      bar: {
        node: 'oscillator',
        output: 'foo',
      },
    });
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 1,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
    virtualAudioGraph.update({});
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [],
    });
  });

  it('changes the node if passed params with same id but different node property', function () {
    virtualAudioGraph.update({
      0: {
        node: 'gain',
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'GainNode',
          gain: {
            value: 1,
            inputs: [],
          },
          inputs: [],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 440,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        },
      ],
    });

    virtualAudioGraph.defineNode(pingPongDelayParamsFactory, 'pingPongDelay');

    virtualAudioGraph.update([{
      id: 0,
      node: 'pingPongDelay',
      output: 'output',
    }]);
    /* eslint-disable */
    expect(audioContext.toJSON()).toEqual({ name: 'AudioDestinationNode', inputs: [ Object({ name: 'OscillatorNode', type: 'sine', frequency: Object({ value: 440, inputs: [  ] }), detune: Object({ value: 0, inputs: [  ] }), inputs: [  ] }), Object({ name: 'StereoPannerNode', pan: Object({ value: 1, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ '<circular:DelayNode>' ] }) ] }) ] }) ] }) ] }), Object({ name: 'StereoPannerNode', pan: Object({ value: -1, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'DelayNode', delayTime: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ Object({ name: 'GainNode', gain: Object({ value: 0.3333333333333333, inputs: [  ] }), inputs: [ '<circular:DelayNode>' ] }) ] }) ] }) ] }) ] }) ] });
    /* eslint-enable */
  });

  it('updates standard and custom nodes if passed same id but different params', function () {
    virtualAudioGraph.update({
      0: {
        node: 'oscillator',
        params: {
          frequency: 220,
          detune: -9,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'OscillatorNode',
        type: 'sine',
        frequency: {
          value: 220,
          inputs: [],
        },
        detune: {
          value: -9,
          inputs: [],
        },
        inputs: [],
      }],
    });

    virtualAudioGraph.update({
      0: {
        node: 'oscillator',
        params: {
          frequency: 880,
          detune: 0,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'OscillatorNode',
        type: 'sine',
        frequency: {
          value: 880,
          inputs: [],
        },
        detune: {
          value: 0,
          inputs: [],
        },
        inputs: [],
      }],
    });

    virtualAudioGraph.defineNode(sineOscFactory, 'sineOscFactory');

    virtualAudioGraph.update({
      0: {
        node: 'sineOscFactory',
        params: {
          frequency: 110,
          gain: 0.5,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 0.5,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 110,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });

    virtualAudioGraph.update({
      0: {
        node: 'sineOscFactory',
        params: {
          frequency: 660,
          gain: 0.2,
        },
        output: 'output',
      },
    });

    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [{
        name: 'GainNode',
        gain: {
          value: 0.2,
          inputs: [],
        },
        inputs: [{
          name: 'OscillatorNode',
          type: 'sine',
          frequency: {
            value: 660,
            inputs: [],
          },
          detune: {
            value: 0,
            inputs: [],
          },
          inputs: [],
        }],
      }],
    });
  });

  it('connects nodes to each other', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    }]);
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      inputs: [
        {
          name: 'GainNode',
          gain: {
            value: 1,
            inputs: [],
          },
          inputs: [
            {
              name: 'OscillatorNode',
              type: 'sine',
              frequency: {
                value: 440,
                inputs: [],
              },
              detune: {
                value: 0,
                inputs: [],
              },
              inputs: [],
            },
          ],
        },
      ],
    });
    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          inputs: [],
        },
      ],
    });
  });

  it('reconnects nodes to each other', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    }]);
    expect(audioContext.toJSON()).toEqual({
      name: 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [],
              },
              'detune': {
                'value': 0,
                'inputs': [],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [],
        },
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          'inputs': [],
        },
      ],
    });
  });

  it('connects and reconnects nodes to audioParams', function () {
    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    },
    {
      id: 2,
      node: 'oscillator',
      output: {key: 1, destination: 'frequency'},
      params: {
        frequency: 0.5,
        type: 'triangle',
      },
    }]);

    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [
                  {
                    'name': 'OscillatorNode',
                    'type': 'triangle',
                    'frequency': {
                      'value': 0.5,
                      'inputs': [],
                    },
                    'detune': {
                      'value': 0,
                      'inputs': [],
                    },
                    'inputs': [],
                  },
                ],
              },
              'detune': {
                'value': 0,
                'inputs': [],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'gain',
      output: 'output',
    },
    {
      id: 1,
      node: 'oscillator',
      output: 0,
    },
    {
      id: 2,
      node: 'oscillator',
      output: [
        {key: 1, destination: 'detune'},
      ],
      params: {
        frequency: 0.5,
        type: 'triangle',
      },
    }]);

    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'GainNode',
          'gain': {
            'value': 1,
            'inputs': [],
          },
          'inputs': [
            {
              'name': 'OscillatorNode',
              'type': 'sine',
              'frequency': {
                'value': 440,
                'inputs': [],
              },
              'detune': {
                'value': 0,
                'inputs': [
                  {
                    'name': 'OscillatorNode',
                    'type': 'triangle',
                    'frequency': {
                      'value': 0.5,
                      'inputs': [],
                    },
                    'detune': {
                      'value': 0,
                      'inputs': [],
                    },
                    'inputs': [],
                  },
                ],
              },
              'inputs': [],
            },
          ],
        },
      ],
    });

    virtualAudioGraph.update([{
      id: 0,
      node: 'oscillator',
      output: 'output',
    }]);
    expect(audioContext.toJSON()).toEqual({
      'name': 'AudioDestinationNode',
      'inputs': [
        {
          'name': 'OscillatorNode',
          'type': 'sine',
          'frequency': {
            'value': 440,
            'inputs': [],
          },
          'detune': {
            'value': 0,
            'inputs': [],
          },
          'inputs': [],
        },
      ],
    });
  });
});
<|endoftext|>


<commit_before>import { ValidationError } from '../lib/validation';

export const LOGIN_ERROR = 'LOGIN_ERROR';
export const LOGIN_START = 'LOGIN_START';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGOUT = 'LOGOUT';

export function login(fields) {
  return ({ fetch, validate }) => {
    const getPromise = async () => {
      try {
        await validate(fields)
          .prop('email').required().email()
          .prop('password').required().simplePassword()
          .promise;
        // Sure we can use smarter api than raw fetch.
        const response = await fetch('/api/v1/auth/login', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(fields)
        });
        if (response.status !== 200) throw response;
        // Return JSON response.
        return response.json();
      } catch (error) {
        // Transform error status to custom error.
        if (error.status === 401) {
          throw new ValidationError('wrongPassword', { prop: 'password' });
        }
        throw error;
      }
    };

    return {
      type: 'LOGIN',
      payload: {
        promise: getPromise()
      }
    };
  };
}

export function logout() {
  return ({ engine, firebase }) => {
    engine.save({});
    firebase.unauth();
    return {
      type: LOGOUT
    };
  };
}
<commit_msg>Fix XHR login on Firebase hosting<commit_after>import { ValidationError } from '../lib/validation';

export const LOGIN_ERROR = 'LOGIN_ERROR';
export const LOGIN_START = 'LOGIN_START';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGOUT = 'LOGOUT';

export function login(fields) {
  return ({ fetch, validate }) => {
    const getPromise = async () => {
      try {
        await validate(fields)
          .prop('email').required().email()
          .prop('password').required().simplePassword()
          .promise;
        // Simulate response for server-less (Firebase hosting) example.
        if (process.env.IS_SERVERLESS) {
          return {
            email: fields.email,
            id: Date.now()
          };
        }
        // Sure we can use smarter api than raw fetch.
        const response = await fetch('/api/v1/auth/login', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(fields)
        });
        if (response.status !== 200) throw response;
        // Return JSON response.
        return response.json();
      } catch (error) {
        // Transform error status to custom error.
        if (error.status === 401) {
          throw new ValidationError('wrongPassword', { prop: 'password' });
        }
        throw error;
      }
    };

    return {
      type: 'LOGIN',
      payload: {
        promise: getPromise()
      }
    };
  };
}

export function logout() {
  return ({ engine, firebase }) => {
    engine.save({});
    firebase.unauth();
    return {
      type: LOGOUT
    };
  };
}
<|endoftext|>


<commit_before>/* global app:true */

(function() {
  'use strict';

  app = app || {};

  app.Project = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      name: '',
      slogan: '',
      company: '',
      companySlogan: '',
      copyrightYear: '',
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.Record = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      'name.full': '',
      company: '',
      phone: '',
      zip: '',
      status: {
        id: undefined,
        name: '',
        userCreated: {}
      },
      userCreated: {}
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.RecordCollection = Backbone.Collection.extend({
    model: app.Record,
    url: '/admin/accounts/',
    parse: function(results) {
      app.pagingView.model.set({
        pages: results.pages,
        items: results.items
      });
      app.filterView.model.set(results.filters);
      return results.data;
    }
  });

  app.Filter = Backbone.Model.extend({
    defaults: {
      search: '',
      status: '',
      sort: '',
      limit: ''
    }
  });

  app.Paging = Backbone.Model.extend({
    defaults: {
      pages: {},
      items: {}
    }
  });

  app.HeaderView = Backbone.View.extend({
    el: '#header',
    template: _.template( $('#tmpl-header').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'addNewOnEnter',
      'click .btn-add': 'addNew'
    },
    initialize: function() {
      this.model = new app.Record();
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    addNewOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      event.preventDefault();
      this.addNew();
    },
    addNew: function() {
      if (this.$el.find('[name="name"]').val() === '') {
        alert('Please enter a name.');
      }
      else {
        this.model.save({
          'name.full': this.$el.find('[name="name"]').val()
        },{
          success: function(model, response) {
            if (response.success) {
              model.id = response.record._id;
              location.href = model.url();
            }
            else {
              alert(response.errors.join('\n'));
            }
          }
        });
      }
    }
  });

  app.ResultsView = Backbone.View.extend({
    el: '#results-table',
    template: _.template( $('#tmpl-results-table').html() ),
    initialize: function() {
      this.collection = new app.RecordCollection( app.mainView.results.data );
      this.listenTo(this.collection, 'reset', this.render);
      this.render();
    },
    render: function() {
      this.$el.html( this.template() );

      var frag = document.createDocumentFragment();
      this.collection.each(function(record) {
        var view = new app.ResultsRowView({ model: record });
        frag.appendChild(view.render().el);
      }, this);
      $('#results-rows').append(frag);

      if (this.collection.length === 0) {
        $('#results-rows').append( $('#tmpl-results-empty-row').html() );
      }
    }
  });

  app.ResultsRowView = Backbone.View.extend({
    tagName: 'tr',
    template: _.template( $('#tmpl-results-row').html() ),
    events: {
      'click .btn-details': 'viewDetails'
    },
    viewDetails: function() {
      location.href = this.model.url();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
      this.$el.find('.timeago').each(function(index, indexValue) {
        if (indexValue.innerText) {
          var myMoment = moment(indexValue.innerText);
          indexValue.innerText = myMoment.from();
          if (indexValue.getAttribute('data-age')) {
            indexValue.innerText = indexValue.innerText.replace('ago', 'old');
          }
        }
      });
      return this;
    }
  });

  app.FilterView = Backbone.View.extend({
    el: '#filters',
    template: _.template( $('#tmpl-filters').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'filterOnEnter',
      'change select': 'filter'
    },
    initialize: function() {
      this.model = new app.Filter( app.mainView.results.filters );
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));

      for (var key in this.model.attributes) {
        if (this.model.attributes.hasOwnProperty(key)) {
          this.$el.find('[name="'+ key +'"]').val(this.model.attributes[key]);
        }
      }
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    filterOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      this.filter();
    },
    filter: function() {
      var query = $('#filters form').serialize();
      Backbone.history.navigate('q/'+ query, { trigger: true });
    }
  });

  app.PagingView = Backbone.View.extend({
    el: '#results-paging',
    template: _.template( $('#tmpl-results-paging').html() ),
    events: {
      'click .btn-page': 'goToPage'
    },
    initialize: function() {
      this.model = new app.Paging({ pages: app.mainView.results.pages, items: app.mainView.results.items });
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      if (this.model.get('pages').total > 1) {
        this.$el.html(this.template( this.model.attributes ));

        if (!this.model.get('pages').hasPrev) {
          this.$el.find('.btn-prev').attr('disabled', 'disabled');
        }

        if (!this.model.get('pages').hasNext) {
          this.$el.find('.btn-next').attr('disabled', 'disabled');
        }
      }
      else {
        this.$el.empty();
      }
    },
    goToPage: function(event) {
      var query = $('#filters form').serialize() +'&page='+ $(event.target).data('page');
      Backbone.history.navigate('q/'+ query, { trigger: true });
      $('body').scrollTop(0);
    }
  });

  app.MainView = Backbone.View.extend({
    el: '.page .container',
    initialize: function() {
      app.mainView = this;
      this.results = JSON.parse( unescape($('#data-results').html()) );

      app.headerView = new app.HeaderView();
      app.resultsView = new app.ResultsView();
      app.filterView = new app.FilterView();
      app.pagingView = new app.PagingView();
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      '': 'default',
      'q/:params': 'query',
      '/about/': 'about',
      'about': 'about2'
    },
    initialize: function() {
      app.mainView = new app.MainView();
    },
    default: function() {
      if (!app.firstLoad) {
        app.resultsView.collection.fetch({ reset: true });
      }

      app.firstLoad = false;
    },
    query: function(params) {
      app.resultsView.collection.fetch({ data: params, reset: true });
      app.firstLoad = false;
    },
    about: function() {
      console.log('router: about');
    },
    about2: function() {
      console.log('router: about2');
    }
  });

  $(document).ready(function() {
    console.log('app loading...');
    app.firstLoad = true;
    app.router = new app.Router();
    Backbone.history.start();
    console.log('app loaded!');
  });
}());
<commit_msg>temporarily disabling backbone views<commit_after>/* global app:true */

(function() {
  'use strict';

  app = app || {};

  app.Project = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      name: '',
      slogan: '',
      company: '',
      companySlogan: '',
      copyrightYear: '',
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.Record = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      'name.full': '',
      company: '',
      phone: '',
      zip: '',
      status: {
        id: undefined,
        name: '',
        userCreated: {}
      },
      userCreated: {}
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.RecordCollection = Backbone.Collection.extend({
    model: app.Record,
    url: '/admin/accounts/',
    parse: function(results) {
      app.pagingView.model.set({
        pages: results.pages,
        items: results.items
      });
      app.filterView.model.set(results.filters);
      return results.data;
    }
  });

  app.Filter = Backbone.Model.extend({
    defaults: {
      search: '',
      status: '',
      sort: '',
      limit: ''
    }
  });

  app.Paging = Backbone.Model.extend({
    defaults: {
      pages: {},
      items: {}
    }
  });

  app.HeaderView = Backbone.View.extend({
    el: '#header',
    template: _.template( $('#tmpl-header').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'addNewOnEnter',
      'click .btn-add': 'addNew'
    },
    initialize: function() {
      this.model = new app.Record();
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    addNewOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      event.preventDefault();
      this.addNew();
    },
    addNew: function() {
      if (this.$el.find('[name="name"]').val() === '') {
        alert('Please enter a name.');
      }
      else {
        this.model.save({
          'name.full': this.$el.find('[name="name"]').val()
        },{
          success: function(model, response) {
            if (response.success) {
              model.id = response.record._id;
              location.href = model.url();
            }
            else {
              alert(response.errors.join('\n'));
            }
          }
        });
      }
    }
  });

  app.ResultsView = Backbone.View.extend({
    el: '#results-table',
    template: _.template( $('#tmpl-results-table').html() ),
    initialize: function() {
      this.collection = new app.RecordCollection( app.mainView.results.data );
      this.listenTo(this.collection, 'reset', this.render);
      this.render();
    },
    render: function() {
      this.$el.html( this.template() );

      var frag = document.createDocumentFragment();
      this.collection.each(function(record) {
        var view = new app.ResultsRowView({ model: record });
        frag.appendChild(view.render().el);
      }, this);
      $('#results-rows').append(frag);

      if (this.collection.length === 0) {
        $('#results-rows').append( $('#tmpl-results-empty-row').html() );
      }
    }
  });

  app.ResultsRowView = Backbone.View.extend({
    tagName: 'tr',
    template: _.template( $('#tmpl-results-row').html() ),
    events: {
      'click .btn-details': 'viewDetails'
    },
    viewDetails: function() {
      location.href = this.model.url();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
      this.$el.find('.timeago').each(function(index, indexValue) {
        if (indexValue.innerText) {
          var myMoment = moment(indexValue.innerText);
          indexValue.innerText = myMoment.from();
          if (indexValue.getAttribute('data-age')) {
            indexValue.innerText = indexValue.innerText.replace('ago', 'old');
          }
        }
      });
      return this;
    }
  });

  app.FilterView = Backbone.View.extend({
    el: '#filters',
    template: _.template( $('#tmpl-filters').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'filterOnEnter',
      'change select': 'filter'
    },
    initialize: function() {
      this.model = new app.Filter( app.mainView.results.filters );
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));

      for (var key in this.model.attributes) {
        if (this.model.attributes.hasOwnProperty(key)) {
          this.$el.find('[name="'+ key +'"]').val(this.model.attributes[key]);
        }
      }
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    filterOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      this.filter();
    },
    filter: function() {
      var query = $('#filters form').serialize();
      Backbone.history.navigate('q/'+ query, { trigger: true });
    }
  });

  app.PagingView = Backbone.View.extend({
    el: '#results-paging',
    template: _.template( $('#tmpl-results-paging').html() ),
    events: {
      'click .btn-page': 'goToPage'
    },
    initialize: function() {
      this.model = new app.Paging({ pages: app.mainView.results.pages, items: app.mainView.results.items });
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      if (this.model.get('pages').total > 1) {
        this.$el.html(this.template( this.model.attributes ));

        if (!this.model.get('pages').hasPrev) {
          this.$el.find('.btn-prev').attr('disabled', 'disabled');
        }

        if (!this.model.get('pages').hasNext) {
          this.$el.find('.btn-next').attr('disabled', 'disabled');
        }
      }
      else {
        this.$el.empty();
      }
    },
    goToPage: function(event) {
      var query = $('#filters form').serialize() +'&page='+ $(event.target).data('page');
      Backbone.history.navigate('q/'+ query, { trigger: true });
      $('body').scrollTop(0);
    }
  });

  app.MainView = Backbone.View.extend({
    el: '.page .container',
    initialize: function() {
      app.mainView = this;
      //this.results = JSON.parse( unescape($('#data-results').html()) );

      //app.headerView = new app.HeaderView();
      //app.resultsView = new app.ResultsView();
      //app.filterView = new app.FilterView();
      //app.pagingView = new app.PagingView();
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      '': 'default',
      'q/:params': 'query',
      '/about/': 'about',
      'about': 'about2'
    },
    initialize: function() {
      app.mainView = new app.MainView();
    },
    default: function() {
      if (!app.firstLoad) {
        app.resultsView.collection.fetch({ reset: true });
      }

      app.firstLoad = false;
    },
    query: function(params) {
      app.resultsView.collection.fetch({ data: params, reset: true });
      app.firstLoad = false;
    },
    about: function() {
      console.log('router: about');
    },
    about2: function() {
      console.log('router: about2');
    }
  });

  $(document).ready(function() {
    console.log('app loading...');
    app.firstLoad = true;
    app.router = new app.Router();
    Backbone.history.start();
    console.log('app loaded!');
  });
}());
<|endoftext|>


<commit_before>var chai = require('chai');
var should = chai.should();
chai.use(require('chai-string'));
var sbgnjs = require('../src/libsbgn');
var renderExt = require('../src/libsbgn-render');
var checkParams = require('../src/utilities').checkParams;
var pkg = require('..');
var annot = sbgnjs.annot;
var N3 = require('n3');
var xml2js = require('xml2js');
var util = require('util');

describe('libsbgn-annotations', function() {
	describe('utilities', function () {
		var simplest, empty, emptyDescription, emptyRelation, emptyBag, inline;
		var doubleDescription, doubleRelation;
		var testID = "http://local/anID000001";
		var testID2 = "http://local/anID000002";
		var testRelation = "http://biomodels.net/model-qualifiers/is";
		var testRelation2 = "http://biomodels.net/model-qualifiers/has";
		var testObject = "http://identifiers.org/biomodels.db/BIOMD0000000004";
		var testObject2 = "http://identifiers.org/biomodels.db/BIOMD0000000005";
		var header =
					'<annotation>'+
					'<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
				    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/">';
		var footer = '</rdf:RDF></annotation>';
		var headerRDF = '<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
				    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/">';
		var footerRDF = '</rdf:RDF>';
		var simplestString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
					'</rdf:Description>';
		var emptyDescriptionString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'</rdf:Description>';
		var emptyRelationString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'<bqmodel:is>'+
					'</bqmodel:is>' +
					'</rdf:Description>';
		var emptyBagString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'<bqmodel:is>'+
					'<rdf:Bag>'+
					'</rdf:Bag>'+
					'</bqmodel:is>'+
					'</rdf:Description>';
		var inlineString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
					'</rdf:Description>';
		var doubleDescriptionString = simplestString +
					'<rdf:Description rdf:about="http://local/anID000002">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000005" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
					'</rdf:Description>';
		var doubleRelationString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
						'<bqmodel:has>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000005" />'+
							'</rdf:Bag>'+
						'</bqmodel:has>'+
					'</rdf:Description>';

		beforeEach('build necessary RDF store from different test inputs', function() {
			simplest = annot.Annotation.fromXML(header+simplestString+footer).rdfElement;
			empty = annot.Annotation.fromXML(header+footer).rdfElement;
			emptyDescription = annot.Annotation.fromXML(header+emptyDescriptionString+footer).rdfElement;
			emptyRelation = annot.Annotation.fromXML(header+emptyRelationString+footer).rdfElement;
			emptyBag = annot.Annotation.fromXML(header+emptyBagString+footer).rdfElement;
			inline = annot.Annotation.fromXML(header+inlineString+footer).rdfElement;
			doubleDescription = annot.Annotation.fromXML(header+doubleDescriptionString+footer).rdfElement;
			doubleRelation = annot.Annotation.fromXML(header+doubleRelationString+footer).rdfElement;

		});

		it('should parse and write xml as is, ignore white space', function(){
			simplest.toXML().should.equalIgnoreSpaces(headerRDF+simplestString+footerRDF);
			empty.toXML().should.equalIgnoreSpaces('<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ></rdf:RDF>');
			emptyDescription.toXML().should.equalIgnoreSpaces('<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ></rdf:RDF>');
			emptyRelation.toXML().should.equalIgnoreSpaces(headerRDF+emptyRelationString+footerRDF);
			emptyBag.toXML().should.equalIgnoreSpaces(headerRDF+emptyBagString+footerRDF);
			inline.toXML().should.equalIgnoreSpaces(headerRDF+inlineString+footerRDF);
		});

		describe('getAllIds', function() {
			it('should return empty list if no ids', function() {
				empty.getAllIds().should.deep.equal([]);
				emptyDescription.getAllIds().should.deep.equal([]);
			});
			it('should return array of ids if elements are present', function() {
				simplest.getAllIds().should.deep.equal([testID]);
				emptyRelation.getAllIds().should.deep.equal([testID]);
				emptyBag.getAllIds().should.deep.equal([testID]);
				inline.getAllIds().should.deep.equal([testID]);
				var doubleRes = doubleDescription.getAllIds();
				doubleRes.should.include(testID);
				doubleRes.should.include(testID2);
			});
		});
		describe('getResourcesOfId', function() {
			it('should return empty list if no resources', function() {
				empty.getResourcesOfId(testID).should.deep.equal({});
				emptyDescription.getResourcesOfId(testID).should.deep.equal({});
			});
			it('should return a single property if only one relation', function() {
				var res = simplest.getResourcesOfId(testID);
				res.should.have.ownProperty(testRelation);
				res[testRelation].should.deep.equal([testObject]);
				//emptyDescription.getResourcesOfId(testID).should.deep.equal({});
			});
		});
	});

	/*it('test', function() {
		var annot = require('../src/libsbgn-annotations');
		// SIO has property !!  "http://semanticscience.org/resource/SIO_000223"
		// SIO name SIO_000116 + rdf:value
		var input1 = '<annotation><rdf:RDF '+
		'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
	    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/" '+
	    'xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" '+
	    'xmlns:sio="http://semanticscience.org/resource/"> '+
		'<rdf:Description rdf:about="http://local/anID000001">  '+
		'	<bqmodel:is> '+
		'		<rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" /> '+
		'		</rdf:Bag> '+
		'	</bqmodel:is> '+

'			<bqmodel:isDescribedBy> '+
'				<rdf:Bag> '+
'					<rdf:li rdf:resource="http://identifiers.org/pubmed/1833774" /> '+
'			</rdf:Bag> '+
'			</bqmodel:isDescribedBy> '+

'			<sio:SIO_000223> '+
	'			<rdf:Bag> '+
	'					<rdf:li sio:SIO_000116="data" rdf:value="42" /> '+
	'					<rdf:li sio:SIO_000116="data2" rdf:value="1.23" /> '+
'				</rdf:Bag> '+
'			</sio:SIO_000223> '+

'		</rdf:Description> '+
'	</rdf:RDF></annotation>';
		var input2 = '<annotation><rdf:RDF '+
		'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
	    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/" '+
	    'xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" '+
	    'xmlns:sio="http://semanticscience.org/resource/"> '+
		'<rdf:Description rdf:about="http://local/anID000002">  '+
		'	<bqmodel:is> '+
		'		<rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+
		'		</rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+
		'	</bqmodel:is> '+
		'<bqmodel:is rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+

'			<bqmodel:isDescribedBy> '+
'				<rdf:Bag> '+
'					<rdf:li rdf:resource="http://identifiers.org/pubmed/PUBMEDID" /> '+
'			</rdf:Bag> '+
'			</bqmodel:isDescribedBy> '+

'			<sio:SIO_000223> '+
	'			<rdf:Bag> '+
	'					<rdf:li sio:SIO_000116="myConstant" rdf:value="42" /> '+
	'					<rdf:li sio:SIO_000116="aProp" rdf:value="123.456" /> '+
'				</rdf:Bag> '+
'			</sio:SIO_000223> '+

'		</rdf:Description> '+
'	</rdf:RDF></annotation>';
		//console.log(input);
		var annotation = annot.Annotation.fromXML(getXmlObj(input1));
		var annotation2 = annot.Annotation.fromXML(getXmlObj(input2));
		var globalStore = new annot.GlobalRdfStore();
		globalStore.load([annotation, annotation2]);
		//console.log(annotation.toXML());
		var rdf = annotation.rdfElements[0];
		//console.log(rdf.toXML());

		//rdf.test();
		//globalStore.test();

	});*/
});
<commit_msg>small update to test annotation element instead of its rdfElement<commit_after>var chai = require('chai');
var should = chai.should();
chai.use(require('chai-string'));
var sbgnjs = require('../src/libsbgn');
var renderExt = require('../src/libsbgn-render');
var checkParams = require('../src/utilities').checkParams;
var pkg = require('..');
var annot = sbgnjs.annot;
var N3 = require('n3');
var xml2js = require('xml2js');
var util = require('util');

describe('libsbgn-annotations', function() {
	describe('utilities', function () {
		var simplest, empty, emptyDescription, emptyRelation, emptyBag, inline;
		var doubleDescription, doubleRelation;
		var testID = "http://local/anID000001";
		var testID2 = "http://local/anID000002";
		var testRelation = "http://biomodels.net/model-qualifiers/is";
		var testRelation2 = "http://biomodels.net/model-qualifiers/has";
		var testObject = "http://identifiers.org/biomodels.db/BIOMD0000000004";
		var testObject2 = "http://identifiers.org/biomodels.db/BIOMD0000000005";
		var header =
					'<annotation>'+
					'<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
				    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/">';
		var footer = '</rdf:RDF></annotation>';
		var headerRDF = '<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
				    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/">';
		var footerRDF = '</rdf:RDF>';
		var simplestString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
					'</rdf:Description>';
		var emptyDescriptionString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'</rdf:Description>';
		var emptyRelationString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'<bqmodel:is>'+
					'</bqmodel:is>' +
					'</rdf:Description>';
		var emptyBagString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
					'<bqmodel:is>'+
					'<rdf:Bag>'+
					'</rdf:Bag>'+
					'</bqmodel:is>'+
					'</rdf:Description>';
		var inlineString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
					'</rdf:Description>';
		var doubleDescriptionString = simplestString +
					'<rdf:Description rdf:about="http://local/anID000002">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000005" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
					'</rdf:Description>';
		var doubleRelationString =
					'<rdf:Description rdf:about="http://local/anID000001">'+
						'<bqmodel:is>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" />'+
							'</rdf:Bag>'+
						'</bqmodel:is>'+
						'<bqmodel:has>'+
							'<rdf:Bag>'+
								'<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000005" />'+
							'</rdf:Bag>'+
						'</bqmodel:has>'+
					'</rdf:Description>';

		beforeEach('build necessary RDF store from different test inputs', function() {
			simplest = annot.Annotation.fromXML(header+simplestString+footer);
			empty = annot.Annotation.fromXML(header+footer).rdfElement;
			emptyDescription = annot.Annotation.fromXML(header+emptyDescriptionString+footer).rdfElement;
			emptyRelation = annot.Annotation.fromXML(header+emptyRelationString+footer).rdfElement;
			emptyBag = annot.Annotation.fromXML(header+emptyBagString+footer).rdfElement;
			inline = annot.Annotation.fromXML(header+inlineString+footer).rdfElement;
			doubleDescription = annot.Annotation.fromXML(header+doubleDescriptionString+footer).rdfElement;
			doubleRelation = annot.Annotation.fromXML(header+doubleRelationString+footer).rdfElement;

		});

		it('should parse and write xml as is, ignore white space', function(){
			simplest.toXML().should.equalIgnoreSpaces("<annotation>"+headerRDF+simplestString+footerRDF+"</annotation>");
			empty.toXML().should.equalIgnoreSpaces('<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ></rdf:RDF>');
			emptyDescription.toXML().should.equalIgnoreSpaces('<rdf:RDF '+
					'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ></rdf:RDF>');
			emptyRelation.toXML().should.equalIgnoreSpaces(headerRDF+emptyRelationString+footerRDF);
			emptyBag.toXML().should.equalIgnoreSpaces(headerRDF+emptyBagString+footerRDF);
			inline.toXML().should.equalIgnoreSpaces(headerRDF+inlineString+footerRDF);
		});

		describe('getAllIds', function() {
			it('should return empty list if no ids', function() {
				empty.getAllIds().should.deep.equal([]);
				emptyDescription.getAllIds().should.deep.equal([]);
			});
			it('should return array of ids if elements are present', function() {
				simplest.rdfElement.getAllIds().should.deep.equal([testID]);
				emptyRelation.getAllIds().should.deep.equal([testID]);
				emptyBag.getAllIds().should.deep.equal([testID]);
				inline.getAllIds().should.deep.equal([testID]);
				var doubleRes = doubleDescription.getAllIds();
				doubleRes.should.include(testID);
				doubleRes.should.include(testID2);
			});
		});
		describe('getResourcesOfId', function() {
			it('should return empty list if no resources', function() {
				empty.getResourcesOfId(testID).should.deep.equal({});
				emptyDescription.getResourcesOfId(testID).should.deep.equal({});
			});
			it('should return a single property if only one relation', function() {
				var res = simplest.rdfElement.getResourcesOfId(testID);
				res.should.have.ownProperty(testRelation);
				res[testRelation].should.deep.equal([testObject]);
				//emptyDescription.getResourcesOfId(testID).should.deep.equal({});
			});
		});
	});

	/*it('test', function() {
		var annot = require('../src/libsbgn-annotations');
		// SIO has property !!  "http://semanticscience.org/resource/SIO_000223"
		// SIO name SIO_000116 + rdf:value
		var input1 = '<annotation><rdf:RDF '+
		'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
	    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/" '+
	    'xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" '+
	    'xmlns:sio="http://semanticscience.org/resource/"> '+
		'<rdf:Description rdf:about="http://local/anID000001">  '+
		'	<bqmodel:is> '+
		'		<rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD0000000004" /> '+
		'		</rdf:Bag> '+
		'	</bqmodel:is> '+

'			<bqmodel:isDescribedBy> '+
'				<rdf:Bag> '+
'					<rdf:li rdf:resource="http://identifiers.org/pubmed/1833774" /> '+
'			</rdf:Bag> '+
'			</bqmodel:isDescribedBy> '+

'			<sio:SIO_000223> '+
	'			<rdf:Bag> '+
	'					<rdf:li sio:SIO_000116="data" rdf:value="42" /> '+
	'					<rdf:li sio:SIO_000116="data2" rdf:value="1.23" /> '+
'				</rdf:Bag> '+
'			</sio:SIO_000223> '+

'		</rdf:Description> '+
'	</rdf:RDF></annotation>';
		var input2 = '<annotation><rdf:RDF '+
		'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" '+
	    'xmlns:bqmodel="http://biomodels.net/model-qualifiers/" '+
	    'xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" '+
	    'xmlns:sio="http://semanticscience.org/resource/"> '+
		'<rdf:Description rdf:about="http://local/anID000002">  '+
		'	<bqmodel:is> '+
		'		<rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+
		'		</rdf:Bag> '+
		'			<rdf:li rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+
		'	</bqmodel:is> '+
		'<bqmodel:is rdf:resource="http://identifiers.org/biomodels.db/BIOMD00000000115" /> '+

'			<bqmodel:isDescribedBy> '+
'				<rdf:Bag> '+
'					<rdf:li rdf:resource="http://identifiers.org/pubmed/PUBMEDID" /> '+
'			</rdf:Bag> '+
'			</bqmodel:isDescribedBy> '+

'			<sio:SIO_000223> '+
	'			<rdf:Bag> '+
	'					<rdf:li sio:SIO_000116="myConstant" rdf:value="42" /> '+
	'					<rdf:li sio:SIO_000116="aProp" rdf:value="123.456" /> '+
'				</rdf:Bag> '+
'			</sio:SIO_000223> '+

'		</rdf:Description> '+
'	</rdf:RDF></annotation>';
		//console.log(input);
		var annotation = annot.Annotation.fromXML(getXmlObj(input1));
		var annotation2 = annot.Annotation.fromXML(getXmlObj(input2));
		var globalStore = new annot.GlobalRdfStore();
		globalStore.load([annotation, annotation2]);
		//console.log(annotation.toXML());
		var rdf = annotation.rdfElements[0];
		//console.log(rdf.toXML());

		//rdf.test();
		//globalStore.test();

	});*/
});
<|endoftext|>


<commit_before>angular.module("gameApp")
    .factory("playerService", ["globalSettings", "gameBoardService", "graphicsEngineService", "sprite", "characterDirection", "characterState", "keyPressHandlerService", "coordinateSystem",
        function(globalSettings, gameBoardService, graphicsEngineService, sprite, characterDirection, characterState, keyPressHandlerService, coordinateSystem) {
        "use strict";

        var player = null;

        function setStartPosition() {
            player.x = Math.floor(globalSettings.gameBoardWidth / 2);
            player.y = globalSettings.gameBoardHeight - 1;
        }

        return {
            createPlayer: function() {
                player = {
                    dx: 0,
                    dy: 0,
                    direction: characterDirection.none,
                    isFiring: false,
                    playerState: characterState.active
                };

                setStartPosition();

                player.prevX = player.x;
                player.prevY = player.y;
            },

            isLocatedLeftOfMiddle: function() {
                return player && player.x < globalSettings.gameBoardWidth / 2;
            },

            die: function() {
                player.playerState = characterState.dead;
            },

            isAlive: function() {
                return player.playerState === characterState.active;
            },

            isFiring: function() {
                return player && player.isFiring;
            },

            regenerate: function(resetToStartPosition) {
                if (resetToStartPosition)
                {
                    setStartPosition();
                }

                player.playerState = characterState.active;
                player.prevX = player.x;
                player.prevY = player.y;
                player.dx = 0;
                player.dy = 0;
                player.direction = characterDirection.none;
            },

            getPreviousPosition: function() {
                return { x: player.prevX, y: player.prevY };
            },

            getPosition: function() {
                return { x: player.x, y: player.y };
            },

            update: function(animation){
                if (!player || player.playerState !== characterState.active) {
                    return;
                }

                if (animation % 2 !== 0) {
                    return;
                }

                var playerMove = keyPressHandlerService.getNextMovement();
                console.log("player move: ", playerMove);
                if (playerMove.direction != characterDirection.none && !gameBoardService.playerAllowedToMove(player.x, player.y, playerMove.direction)) {

                    console.log("player can move!");
                    playerMove.direction = characterDirection.none;
                }

                player.prevX = player.x;
                player.prevY = player.y;
                player.direction = playerMove.direction;
                player.isFiring = playerMove.isFiring;

                switch (playerMove.direction) {
                    case characterDirection.none:
                        player.dx = 0;
                        player.dy = 0;
                        break;

                    case characterDirection.left:
                        player.x -= 1;
                        player.dx = -0.5;
                        player.dy = 0;
                        break;

                    case characterDirection.right:
                        player.x += 1;
                        player.dx = 0.5;
                        player.dy = 0;
                        break;

                    case characterDirection.up:
                        player.y -= 1;
                        player.dx = 0;
                        player.dy = -0.5;
                        break;

                    case characterDirection.down:
                        player.y += 1;
                        player.dx = 0;
                        player.dy = 0.5;
                        break;
                }
            },

            draw: function(animation) {
                if (!player) {
                    return;
                }

                var destX;
                var destY;
                var image;

                if (player.playerState !== characterState.active) {
                    image = sprite.explosion;
                    destX = player.x;
                    destY = player.y;
                } else {
                    image = sprite.playerStandStill;
                    destX = player.prevX + ((animation % 2) * player.dx);
                    destY = player.prevY + ((animation % 2) * player.dy);

                    switch (player.direction)
                    {
                        case characterDirection.right:
                            image = sprite.playerWalkRight1 + animation;
                            break;

                        case characterDirection.left:
                            image = sprite.playerWalkLeft1 + animation;
                            break;

                        case characterDirection.none:
                            if (player.isFiring) {
                                image = sprite.playerFire;
                            }
                            break;
                    }
                }

                graphicsEngineService.drawImage(coordinateSystem.world, destX, destY, image);
            }
        }
    }]);
<commit_msg>process<commit_after>angular.module("gameApp")
    .factory("playerService", ["globalSettings", "gameBoardService", "graphicsEngineService", "sprite", "characterDirection", "characterState", "keyPressHandlerService", "coordinateSystem",
        function(globalSettings, gameBoardService, graphicsEngineService, sprite, characterDirection, characterState, keyPressHandlerService, coordinateSystem) {
        "use strict";

        var player = null;

        function setStartPosition() {
            player.x = Math.floor(globalSettings.gameBoardWidth / 2);
            player.y = globalSettings.gameBoardHeight - 1;
        }

        return {
            createPlayer: function() {
                player = {
                    dx: 0,
                    dy: 0,
                    direction: characterDirection.none,
                    isFiring: false,
                    playerState: characterState.active
                };

                setStartPosition();

                player.prevX = player.x;
                player.prevY = player.y;
            },

            isLocatedLeftOfMiddle: function() {
                return player && player.x < globalSettings.gameBoardWidth / 2;
            },

            die: function() {
                player.playerState = characterState.dead;
            },

            isAlive: function() {
                return player.playerState === characterState.active;
            },

            isFiring: function() {
                return player && player.isFiring;
            },

            regenerate: function(resetToStartPosition) {
                if (resetToStartPosition)
                {
                    setStartPosition();
                }

                player.playerState = characterState.active;
                player.prevX = player.x;
                player.prevY = player.y;
                player.dx = 0;
                player.dy = 0;
                player.direction = characterDirection.none;
            },

            getPreviousPosition: function() {
                return { x: player.prevX, y: player.prevY };
            },

            getPosition: function() {
                return { x: player.x, y: player.y };
            },

            update: function(animation){
                if (!player || player.playerState !== characterState.active) {
                    return;
                }

                if (animation % 2 !== 0) {
                    return;
                }

                var playerMove = keyPressHandlerService.getNextMovement();

                if (playerMove.direction != characterDirection.none && !gameBoardService.playerAllowedToMove(player.x, player.y, playerMove.direction)) {

                    console.log("player can move!");
                    playerMove.direction = characterDirection.none;
                }

                player.prevX = player.x;
                player.prevY = player.y;
                player.direction = playerMove.direction;
                player.isFiring = playerMove.isFiring;

                switch (playerMove.direction) {
                    case characterDirection.none:
                        player.dx = 0;
                        player.dy = 0;
                        break;

                    case characterDirection.left:
                        player.x -= 1;
                        player.dx = -0.5;
                        player.dy = 0;
                        break;

                    case characterDirection.right:
                        player.x += 1;
                        player.dx = 0.5;
                        player.dy = 0;
                        break;

                    case characterDirection.up:
                        player.y -= 1;
                        player.dx = 0;
                        player.dy = -0.5;
                        break;

                    case characterDirection.down:
                        player.y += 1;
                        player.dx = 0;
                        player.dy = 0.5;
                        break;
                }
            },

            draw: function(animation) {
                if (!player) {
                    return;
                }

                var destX;
                var destY;
                var image;

                if (player.playerState !== characterState.active) {
                    image = sprite.explosion;
                    destX = player.x;
                    destY = player.y;
                } else {
                    image = sprite.playerStandStill;
                    destX = player.prevX + ((animation % 2) * player.dx);
                    destY = player.prevY + ((animation % 2) * player.dy);

                    switch (player.direction)
                    {
                        case characterDirection.right:
                            image = sprite.playerWalkRight1 + animation;
                            break;

                        case characterDirection.left:
                            image = sprite.playerWalkLeft1 + animation;
                            break;

                        case characterDirection.none:
                            if (player.isFiring) {
                                image = sprite.playerFire;
                            }
                            break;
                    }
                }

                graphicsEngineService.drawImage(coordinateSystem.world, destX, destY, image);
            }
        }
    }]);
<|endoftext|>


<commit_before>
var monkeyscript = {
	version: '0.0.0.0a',
	hooks: {},
	rc: [],
	included: []
};

(function(_native) {
	delete global._native;

	// Arguments
	var args = Array.slice(_native.arguments);
	if ( args[0] === '-h' ) {
		args.shift();
		monkeyscript.hookName = args.shift();
	} else {
		monkeyscript.scriptName = args.shift();
	}

	//Object.seal(args); // @ES5
	monkeyscript.arguments = args;
	global.arguments = Array.slice(args);

	global.Kernel = _native.Kernel;
	//Object.seal(Kernel); // @ES5

	monkeyscript.rc.push(
		Kernel.configDir + Kernel.os.fileSeparator + 'monkeyscriptrc.js',
		Kernel.configDir + Kernel.os.fileSeparator + 'monkeyscriptrc'
	);
	var baseNames = ['.monkeyscriptrc.js', '.monkeyscriptrc'];
	[
		Kernel.home,
		Kernel.currentWorkingDirectory
	].forEach(function(basePath) {
		baseNames.forEach(function(baseName) {
			monkeyscript.rc.push( basePath + Kernel.os.fileSeparator + baseName );
		});
	});
	//Object.seal(monkeyscript.rc); // @ES5

})(_native);

// Setup global Error objects
var IOError = Kernel.newError("IOError");

//for each( let rc in monkeyscript.rc ) // Rhino's __iterator__ is broken atm
for ( let k in monkeyscript.rc ) {
	var rc = monkeyscript.rc[k];
	try { include.ifExists(rc); }
	// Other errors will be printed, but still not affect running the script
	catch( e ) { print(e); }
}

if ( monkeyscript.hookName ) {
	let scriptName = monkeyscript.hooks[monkeyscript.hookName];
	if ( scriptName )
		include(scriptName);
	else
		throw new Error("The hook "+monkeyscript.hookName+" does not exist");
} else if ( monkeyscript.scriptName ) {
	if ( monkeyscript.scriptName.startsWith('javascript:') )
		eval(monkeyscript.scriptName.substr('javascript:'.length));
	else
		include(monkeyscript.scriptName);
} else
	throw new Error("No script specified");

<commit_msg>This bug is fixed in the new Rhino<commit_after>
var monkeyscript = {
	version: '0.0.0.0a',
	hooks: {},
	rc: [],
	included: []
};

(function(_native) {
	delete global._native;

	// Arguments
	var args = Array.slice(_native.arguments);
	if ( args[0] === '-h' ) {
		args.shift();
		monkeyscript.hookName = args.shift();
	} else {
		monkeyscript.scriptName = args.shift();
	}

	//Object.seal(args); // @ES5
	monkeyscript.arguments = args;
	global.arguments = Array.slice(args);

	global.Kernel = _native.Kernel;
	//Object.seal(Kernel); // @ES5

	monkeyscript.rc.push(
		Kernel.configDir + Kernel.os.fileSeparator + 'monkeyscriptrc.js',
		Kernel.configDir + Kernel.os.fileSeparator + 'monkeyscriptrc'
	);
	var baseNames = ['.monkeyscriptrc.js', '.monkeyscriptrc'];
	[
		Kernel.home,
		Kernel.currentWorkingDirectory
	].forEach(function(basePath) {
		baseNames.forEach(function(baseName) {
			monkeyscript.rc.push( basePath + Kernel.os.fileSeparator + baseName );
		});
	});
	//Object.seal(monkeyscript.rc); // @ES5

})(_native);

// Setup global Error objects
var IOError = Kernel.newError("IOError");

for each( let rc in monkeyscript.rc ) {
	try { include.ifExists(rc); }
	// Other errors will be printed, but still not affect running the script
	catch( e ) { print(e); }
}

if ( monkeyscript.hookName ) {
	let scriptName = monkeyscript.hooks[monkeyscript.hookName];
	if ( scriptName )
		include(scriptName);
	else
		throw new Error("The hook "+monkeyscript.hookName+" does not exist");
} else if ( monkeyscript.scriptName ) {
	if ( monkeyscript.scriptName.startsWith('javascript:') )
		eval(monkeyscript.scriptName.substr('javascript:'.length));
	else
		include(monkeyscript.scriptName);
} else
	throw new Error("No script specified");

<|endoftext|>