<commit_before>'use strict';

const expect = require('chai').expect;

const MockUI = require('console-ui/mock');
const MockAnalytics = require('../../helpers/mock-analytics');
const MockWatcher = require('../../helpers/mock-watcher');
const MockBroccoliWatcher = require('../../helpers/mock-broccoli-watcher');
const Watcher = require('../../../lib/models/watcher');
const EOL = require('os').EOL;
const chalk = require('chalk');
const BuildError = require('../../helpers/build-error');
const { isExperimentEnabled } = require('../../../lib/experiments');
const buildEvent = isExperimentEnabled('BROCCOLI_WATCHER') ? 'buildSuccess' : 'change';

describe('Watcher', function() {
  let ui;
  let subject;
  let builder;
  let analytics;
  let watcher;

  let mockResult = {
    totalTime: 12344000000,
    graph: {
      __heimdall__: {
        visitPreOrder(cb) {
          return cb({
            stats: {
              time: {
                self: 12344000000,
              },
            },
          });
        },
        visitPostOrder() {},
      },
    },
  };

  beforeEach(function() {
    ui = new MockUI();
    analytics = new MockAnalytics();

    if (isExperimentEnabled('BROCCOLI_WATCHER')) {
      watcher = new MockBroccoliWatcher();
    } else {
      watcher = new MockWatcher();
    }

    subject = new Watcher({
      ui,
      analytics,
      builder,
      watcher,
    });
  });

  describe('watcher strategy selection', function() {
    it('selects the events-based watcher by default', function() {
      subject.options = null;

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: false,
        watchman: false,
        node: false,
      });
    });

    it('selects the events-based watcher when given events watcher option', function() {
      subject.options = {
        watcher: 'events',
      };

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: false,
        watchman: true,
        node: false,
      });
    });

    it('selects the polling watcher when given polling watcher option', function() {
      subject.options = {
        watcher: 'polling',
      };

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: true,
        watchman: false,
        node: false,
      });
    });
  });

  if (isExperimentEnabled('BROCCOLI_WATCHER')) {
    describe('watcher:change', function() {
      beforeEach(function() {
        watcher.emit('change', 'change', 'foo.txt');
      });

      it('logs that the file was changed', function() {
        expect(ui.output).to.equal(`file changed foo.txt${EOL}`);
      });
    });
  }

  describe(`watcher:${buildEvent}`, function() {
    beforeEach(function() {
      watcher.emit(buildEvent, mockResult);
    });

    it('tracks events', function() {
      expect(analytics.tracks).to.deep.equal([
        {
          name: 'ember rebuild',
          message: 'broccoli rebuild time: 12344ms',
        },
      ]);
    });

    it('tracks timings', function() {
      expect(analytics.trackTimings).to.deep.equal([
        {
          category: 'rebuild',
          variable: 'rebuild time',
          label: 'broccoli rebuild time',
          value: 12344,
        },
      ]);
    });

    it('logs that the build was successful', function() {
      expect(ui.output).to.equal(EOL + chalk.green('Build successful (12344ms)') + EOL);
    });
  });

  describe('output', function() {
    this.timeout(40000);

    it('with ssl', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          ssl: true,
          sslCert: 'tests/fixtures/ssl/server.crt',
          sslKey: 'tests/fixtures/ssl/server.key',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '/',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on https://localhost:1337/`);
    });

    it('with baseURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          environment: 'development',
          project: {
            config() {
              return {
                baseURL: '/foo',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(
        `${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/foo/`
      );
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with rootURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '/foo',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);

      expect(output[0]).to.equal(
        `${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/foo/`
      );
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with empty rootURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          rootURL: '',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/`);
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with customURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          rootURL: '',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '',
              };
            },
          },
        },
      });
      subject.serveURL = function() {
        return `http://customurl.com/`;
      };
      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on http://customurl.com/`);
    });
  });

  describe('watcher:error', function() {
    it('tracks errors', function() {
      watcher.emit('error', {
        message: 'foo',
        stack: new Error().stack,
      });

      expect(analytics.trackErrors).to.deep.equal([
        {
          description: undefined,
        },
      ]);
    });

    it('emits without error.file', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.equal('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file with error.line without err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          line: 24,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile:24'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file without error.line with err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          col: 80,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file with error.line with err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          line: 24,
          col: 80,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile:24:80'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });
  });

  describe('watcher:change afterError', function() {
    beforeEach(function() {
      watcher.emit('error', {
        message: 'foo',
        stack: new Error().stack,
      });

      watcher.emit(buildEvent, mockResult);
    });

    it('log that the build was green', function() {
      expect(ui.output).to.match(/Build successful./, 'has successful build output');
    });

    it('keep tracking analytics', function() {
      expect(analytics.tracks).to.deep.equal([
        {
          name: 'ember rebuild',
          message: 'broccoli rebuild time: 12344ms',
        },
      ]);
    });
  });
});
<commit_msg>Adding final test<commit_after>'use strict';

const expect = require('chai').expect;

const MockUI = require('console-ui/mock');
const MockAnalytics = require('../../helpers/mock-analytics');
const MockWatcher = require('../../helpers/mock-watcher');
const MockBroccoliWatcher = require('../../helpers/mock-broccoli-watcher');
const Watcher = require('../../../lib/models/watcher');
const EOL = require('os').EOL;
const chalk = require('chalk');
const BuildError = require('../../helpers/build-error');
const { isExperimentEnabled } = require('../../../lib/experiments');
const buildEvent = isExperimentEnabled('BROCCOLI_WATCHER') ? 'buildSuccess' : 'change';

describe('Watcher', function() {
  let ui;
  let subject;
  let builder;
  let analytics;
  let watcher;

  let mockResult = {
    totalTime: 12344000000,
    graph: {
      __heimdall__: {
        visitPreOrder(cb) {
          return cb({
            stats: {
              time: {
                self: 12344000000,
              },
            },
          });
        },
        visitPostOrder() {},
      },
    },
  };

  beforeEach(function() {
    ui = new MockUI();
    analytics = new MockAnalytics();

    if (isExperimentEnabled('BROCCOLI_WATCHER')) {
      watcher = new MockBroccoliWatcher();
    } else {
      watcher = new MockWatcher();
    }

    subject = new Watcher({
      ui,
      analytics,
      builder,
      watcher,
    });
  });

  describe('watcher strategy selection', function() {
    it('selects the events-based watcher by default', function() {
      subject.options = null;

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: false,
        watchman: false,
        node: false,
      });
    });

    it('selects the events-based watcher when given events watcher option', function() {
      subject.options = {
        watcher: 'events',
      };

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: false,
        watchman: true,
        node: false,
      });
    });

    it('selects the polling watcher when given polling watcher option', function() {
      subject.options = {
        watcher: 'polling',
      };

      expect(subject.buildOptions()).to.deep.equal({
        verbose: true,
        poll: true,
        watchman: false,
        node: false,
      });
    });
  });

  if (isExperimentEnabled('BROCCOLI_WATCHER')) {
    describe('underlining watcher properly logs change events', function() {
      it('logs that the file was added', function() {
        watcher.emit('change', 'add', 'foo.txt');
        expect(ui.output).to.equal(`file added foo.txt${EOL}`);
      });
      it('logs that the file was changed', function() {
        watcher.emit('change', 'change', 'foo.txt');
        expect(ui.output).to.equal(`file changed foo.txt${EOL}`);
      });
      it('logs that the file was deleted', function() {
        watcher.emit('change', 'delete', 'foo.txt');
        expect(ui.output).to.equal(`file deleted foo.txt${EOL}`);
      });
    });
  }

  describe(`watcher:${buildEvent}`, function() {
    beforeEach(function() {
      watcher.emit(buildEvent, mockResult);
    });

    it('tracks events', function() {
      expect(analytics.tracks).to.deep.equal([
        {
          name: 'ember rebuild',
          message: 'broccoli rebuild time: 12344ms',
        },
      ]);
    });

    it('tracks timings', function() {
      expect(analytics.trackTimings).to.deep.equal([
        {
          category: 'rebuild',
          variable: 'rebuild time',
          label: 'broccoli rebuild time',
          value: 12344,
        },
      ]);
    });

    it('logs that the build was successful', function() {
      expect(ui.output).to.equal(EOL + chalk.green('Build successful (12344ms)') + EOL);
    });
  });

  describe('output', function() {
    this.timeout(40000);

    it('with ssl', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          ssl: true,
          sslCert: 'tests/fixtures/ssl/server.crt',
          sslKey: 'tests/fixtures/ssl/server.key',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '/',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on https://localhost:1337/`);
    });

    it('with baseURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          environment: 'development',
          project: {
            config() {
              return {
                baseURL: '/foo',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(
        `${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/foo/`
      );
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with rootURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '/foo',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);

      expect(output[0]).to.equal(
        `${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/foo/`
      );
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with empty rootURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          rootURL: '',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '',
              };
            },
          },
        },
      });

      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on http://localhost:1337/`);
      expect(output.length).to.equal(1, 'expected only one line of output');
    });

    it('with customURL', function() {
      let subject = new Watcher({
        ui,
        analytics,
        builder,
        watcher,
        serving: true,
        options: {
          host: undefined,
          port: '1337',
          rootURL: '',
          environment: 'development',
          project: {
            config() {
              return {
                rootURL: '',
              };
            },
          },
        },
      });
      subject.serveURL = function() {
        return `http://customurl.com/`;
      };
      subject.didChange(mockResult);

      let output = ui.output.trim().split(EOL);
      expect(output[0]).to.equal(`${chalk.green('Build successful (12344ms)')} – Serving on http://customurl.com/`);
    });
  });

  describe('watcher:error', function() {
    it('tracks errors', function() {
      watcher.emit('error', {
        message: 'foo',
        stack: new Error().stack,
      });

      expect(analytics.trackErrors).to.deep.equal([
        {
          description: undefined,
        },
      ]);
    });

    it('emits without error.file', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.equal('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file with error.line without err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          line: 24,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile:24'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file without error.line with err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          col: 80,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });

    it('emits with error.file with error.line with err.col', function() {
      subject.didError(
        new BuildError({
          file: 'someFile',
          line: 24,
          col: 80,
          message: 'buildFailed',
        })
      );

      expect(ui.output).to.eql('');

      let outs = ui.errors.split(EOL);

      expect(outs[0]).to.equal(chalk.red('File: someFile:24:80'));
      expect(outs[2]).to.equal(chalk.red('buildFailed'));
    });
  });

  describe('watcher:change afterError', function() {
    beforeEach(function() {
      watcher.emit('error', {
        message: 'foo',
        stack: new Error().stack,
      });

      watcher.emit(buildEvent, mockResult);
    });

    it('log that the build was green', function() {
      expect(ui.output).to.match(/Build successful./, 'has successful build output');
    });

    it('keep tracking analytics', function() {
      expect(analytics.tracks).to.deep.equal([
        {
          name: 'ember rebuild',
          message: 'broccoli rebuild time: 12344ms',
        },
      ]);
    });
  });
});
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * 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 Gregg Tavares. 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 THE COPYRIGHT
 * OWNER OR CONTRIBUTORS 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.
 */
"use strict";

define([
    '../bower_components/hft-utils/dist/imageutils',
  ], function(ImageUtils) {

  var avatars = [
    { name: "spider",
      baseColor: [0xC9,0xA0,0x00],
      range: [0.00, 1.0],
      scale: 0.6,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/spider/spider_walk1.png",
            "assets/avatars/spider/spider_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/spider/spider.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/spider/spider.png",
          ],
        },
      },
    },
    { name: "alienYellow",
      baseColor: [0xFF,0xD6,0x33],
      range: [0.00, -0.02],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_walk1.png",
            "assets/avatars/alien_sprites/alienYellow_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_jump.png",
          ],
        },
      },
    },
    { name: "alienPink",
      baseColor: [0xF3,0xAF,0xC5],
      range: [0.00, -0.02],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_walk1.png",
            "assets/avatars/alien_sprites/alienPink_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_jump.png",
          ],
        },
      },
    },
    { name: "alienGreen",
      baseColor: [0x8B,0xCF,0xBA],
      range: [0.00, -0.02],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_walk1.png",
            "assets/avatars/alien_sprites/alienGreen_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_jump.png",
          ],
        },
      },
    },
    { name: "alienBlue",
      baseColor: [0xA3,0xC3,0xEB],
      range: [0.00, -0.02],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_walk1.png",
            "assets/avatars/alien_sprites/alienBlue_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_jump.png",
          ],
        },
      },
    },
    { name: "alienBeige",
      baseColor: [0xE6,0xDA,0xBF],
      range: [0.00, -0.02],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_walk1.png",
            "assets/avatars/alien_sprites/alienBeige_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_jump.png",
          ],
        },
      },
    },
    { name: "wasler",
      baseColor: [0xFF,0x00,0x00],
      range: [0.00, 0.02],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/wasler/walk/r/1.png",
            "assets/avatars/wasler/walk/r/2.png",
            "assets/avatars/wasler/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/wasler/idle/r/1.png",
            "assets/avatars/wasler/idle/r/2.png",
            "assets/avatars/wasler/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/wasler/jump/r/1.png",
            "assets/avatars/wasler/jump/r/2.png",
            "assets/avatars/wasler/jump/r/3.png",
          ],
        },
      },
    },
    { name: "sara",
      baseColor: [0x25,0x41,0x89],
      range: [0.2, 0.9],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/sara/walk/r/1.png",
            "assets/avatars/sara/walk/r/2.png",
            "assets/avatars/sara/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/sara/idle/r/1.png",
            "assets/avatars/sara/idle/r/2.png",
            "assets/avatars/sara/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/sara/jump/r/1.png",
            "assets/avatars/sara/jump/r/2.png",
            "assets/avatars/sara/jump/r/3.png",
          ],
        },
      },
    },
    { name: "gnu",
      baseColor: [0xB6, 0x7A, 0x3D],
      range: [0, 0.05],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/gnu/walk/r/1.png",
            "assets/avatars/gnu/walk/r/2.png",
            "assets/avatars/gnu/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/gnu/idle/r/1.png",
            "assets/avatars/gnu/idle/r/2.png",
            "assets/avatars/gnu/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/gnu/jump/r/1.png",
            "assets/avatars/gnu/jump/r/2.png",
            "assets/avatars/gnu/jump/r/3.png",
          ],
        },
      },
    },
    { name: "wilber",
      baseColor: [0x6D,0x4C,0x10],
      range: [0.1, 0.2],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/wilber/walk/r/1.png",
            "assets/avatars/wilber/walk/r/2.png",
            "assets/avatars/wilber/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/wilber/idle/r/1.png",
            "assets/avatars/wilber/idle/r/2.png",
            "assets/avatars/wilber/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/wilber/jump/r/1.png",
            "assets/avatars/wilber/jump/r/2.png",
            "assets/avatars/wilber/jump/r/3.png",
          ],
        },
      },
    },
    { name: "kisi",
      baseColor: [0x00,0x32,0x66],
      range: [0.5, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/kisi/walk/r/1.png",
            "assets/avatars/kisi/walk/r/2.png",
            "assets/avatars/kisi/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/kisi/idle/r/1.png",
            "assets/avatars/kisi/idle/r/2.png",
            "assets/avatars/kisi/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/kisi/jump/r/1.png",
            "assets/avatars/kisi/jump/r/2.png",
            "assets/avatars/kisi/jump/r/3.png",
          ],
        },
      },
    },
    { name: "tux",
      baseColor: [0xFF,0xA4,0x04],
      range: [0.05, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/tux/walk/r/1.png",
            "assets/avatars/tux/walk/r/2.png",
            "assets/avatars/tux/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/tux/idle/r/1.png",
            "assets/avatars/tux/idle/r/2.png",
            "assets/avatars/tux/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/tux/jump/r/1.png",
            "assets/avatars/tux/jump/r/2.png",
            "assets/avatars/tux/jump/r/3.png",
          ],
        },
      },
    },
    { name: "kit",
      baseColor: [0xFF,0x57,0x00],
      range: [0, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/kit/walk/r/1.png",
            "assets/avatars/kit/walk/r/2.png",
            "assets/avatars/kit/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/kit/idle/r/1.png",
            "assets/avatars/kit/idle/r/2.png",
            "assets/avatars/kit/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/kit/jump/r/1.png",
            "assets/avatars/kit/jump/r/2.png",
            "assets/avatars/kit/jump/r/3.png",
          ],
        },
      },
    },
    { name: "blocky",
      baseColor: [0x17, 0x7C, 0x69],  // the base color of the part that changes colors
      range: [0.4, 0.6],              // the hue range to adjust. Only hues in this range will be affected
      scale: 1,                       // Can be used to slightly scale a sprite that's too small
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,

      // for the animations:
      //   scale:  how much to scale UP the sprite using nearest neighbor
      //   slices: how large each slice is before it's scaled. Now this can also be an array
      //           in which case each entry is the width of a slice starting from the left.
      //   if slices is NOT specifed the entire file is just one frame.

      anims: {
        move: { url: "assets/avatars/blocky/blocky_walkright.png", scale: 2, slices: 16, },
        idle: { url: "assets/avatars/blocky/blocky_right.png",     scale: 2, slices: 16, },
        jump: { url: "assets/avatars/blocky/blocky_walkright.png", scale: 2, slices: 16, },
      },
    },
    { name: "miyamoto",
      baseColor: [0x8A, 0x56, 0x24],
      range: [0.078, 0.1],
      scale: 32/27,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      anims: {
        move: { url: "assets/avatars/miyamoto/run.png", scale: 1, slices: 20, },
        idle: { url: "assets/avatars/miyamoto/idle.png", },
        jump: { url: "assets/avatars/miyamoto/jump.png", scale: 1, slices: 19, },
      },
    },
    { name: "bird",
      baseColor: [0x00, 0x98, 0xCC],
      range: [180 / 360, 275 / 360],  // color range for colorizing duck but not beak
      scale: 1,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      anims: {
        idle:  { url: "assets/spr_idle.png",    scale: 2, slices: 16, },
        move:  { url: "assets/spr_run.png",     scale: 2, slices: 16, },
        jump:  { url: "assets/spr_jump.png",    scale: 2, slices: [16, 17, 17, 18, 16, 16] },
      },
    },
  ];

  avatars.forEach(function(avatar) {
    var c = avatar.baseColor;
    avatar.baseHSV = ImageUtils.rgbToHsv(c[0], c[1], c[2]);
  });

  return avatars;
});

<commit_msg>fix color ranges for aliens<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * 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 Gregg Tavares. 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 THE COPYRIGHT
 * OWNER OR CONTRIBUTORS 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.
 */
"use strict";

define([
    '../bower_components/hft-utils/dist/imageutils',
  ], function(ImageUtils) {

  var avatars = [
    { name: "spider",
      baseColor: [0xC9,0xA0,0x00],
      range: [0.00, 1.0],
      scale: 0.6,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/spider/spider_walk1.png",
            "assets/avatars/spider/spider_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/spider/spider.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/spider/spider.png",
          ],
        },
      },
    },
    { name: "alienYellow",
      baseColor: [0xFF,0xD6,0x33],
      range: [0.00, 1],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_walk1.png",
            "assets/avatars/alien_sprites/alienYellow_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienYellow_jump.png",
          ],
        },
      },
    },
    { name: "alienPink",
      baseColor: [0xF3,0xAF,0xC5],
      range: [0.00, 1],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_walk1.png",
            "assets/avatars/alien_sprites/alienPink_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienPink_jump.png",
          ],
        },
      },
    },
    { name: "alienGreen",
      baseColor: [0x8B,0xCF,0xBA],
      range: [0.00, 1],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_walk1.png",
            "assets/avatars/alien_sprites/alienGreen_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienGreen_jump.png",
          ],
        },
      },
    },
    { name: "alienBlue",
      baseColor: [0xA3,0xC3,0xEB],
      range: [0.00, 1],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_walk1.png",
            "assets/avatars/alien_sprites/alienBlue_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienBlue_jump.png",
          ],
        },
      },
    },
    { name: "alienBeige",
      baseColor: [0xE6,0xDA,0xBF],
      range: [0.00, 1],
      scale: 0.4,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_walk1.png",
            "assets/avatars/alien_sprites/alienBeige_walk2.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_stand.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/alien_sprites/alienBeige_jump.png",
          ],
        },
      },
    },
    { name: "wasler",
      baseColor: [0xFF,0x00,0x00],
      range: [0.00, 0.02],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/wasler/walk/r/1.png",
            "assets/avatars/wasler/walk/r/2.png",
            "assets/avatars/wasler/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/wasler/idle/r/1.png",
            "assets/avatars/wasler/idle/r/2.png",
            "assets/avatars/wasler/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/wasler/jump/r/1.png",
            "assets/avatars/wasler/jump/r/2.png",
            "assets/avatars/wasler/jump/r/3.png",
          ],
        },
      },
    },
    { name: "sara",
      baseColor: [0x25,0x41,0x89],
      range: [0.2, 0.9],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/sara/walk/r/1.png",
            "assets/avatars/sara/walk/r/2.png",
            "assets/avatars/sara/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/sara/idle/r/1.png",
            "assets/avatars/sara/idle/r/2.png",
            "assets/avatars/sara/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/sara/jump/r/1.png",
            "assets/avatars/sara/jump/r/2.png",
            "assets/avatars/sara/jump/r/3.png",
          ],
        },
      },
    },
    { name: "gnu",
      baseColor: [0xB6, 0x7A, 0x3D],
      range: [0, 0.05],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/gnu/walk/r/1.png",
            "assets/avatars/gnu/walk/r/2.png",
            "assets/avatars/gnu/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/gnu/idle/r/1.png",
            "assets/avatars/gnu/idle/r/2.png",
            "assets/avatars/gnu/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/gnu/jump/r/1.png",
            "assets/avatars/gnu/jump/r/2.png",
            "assets/avatars/gnu/jump/r/3.png",
          ],
        },
      },
    },
    { name: "wilber",
      baseColor: [0x6D,0x4C,0x10],
      range: [0.1, 0.2],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/wilber/walk/r/1.png",
            "assets/avatars/wilber/walk/r/2.png",
            "assets/avatars/wilber/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/wilber/idle/r/1.png",
            "assets/avatars/wilber/idle/r/2.png",
            "assets/avatars/wilber/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/wilber/jump/r/1.png",
            "assets/avatars/wilber/jump/r/2.png",
            "assets/avatars/wilber/jump/r/3.png",
          ],
        },
      },
    },
    { name: "kisi",
      baseColor: [0x00,0x32,0x66],
      range: [0.5, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/kisi/walk/r/1.png",
            "assets/avatars/kisi/walk/r/2.png",
            "assets/avatars/kisi/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/kisi/idle/r/1.png",
            "assets/avatars/kisi/idle/r/2.png",
            "assets/avatars/kisi/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/kisi/jump/r/1.png",
            "assets/avatars/kisi/jump/r/2.png",
            "assets/avatars/kisi/jump/r/3.png",
          ],
        },
      },
    },
    { name: "tux",
      baseColor: [0xFF,0xA4,0x04],
      range: [0.05, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/tux/walk/r/1.png",
            "assets/avatars/tux/walk/r/2.png",
            "assets/avatars/tux/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/tux/idle/r/1.png",
            "assets/avatars/tux/idle/r/2.png",
            "assets/avatars/tux/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/tux/jump/r/1.png",
            "assets/avatars/tux/jump/r/2.png",
            "assets/avatars/tux/jump/r/3.png",
          ],
        },
      },
    },
    { name: "kit",
      baseColor: [0xFF,0x57,0x00],
      range: [0, 1],
      scale: 0.5,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      filter: false,
      anims: {
        move: {
          urls: [
            "assets/avatars/kit/walk/r/1.png",
            "assets/avatars/kit/walk/r/2.png",
            "assets/avatars/kit/walk/r/3.png",
          ],
        },
        idle: {
          urls: [
            "assets/avatars/kit/idle/r/1.png",
            "assets/avatars/kit/idle/r/2.png",
            "assets/avatars/kit/idle/r/3.png",
          ],
        },
        jump: {
          urls: [
            "assets/avatars/kit/jump/r/1.png",
            "assets/avatars/kit/jump/r/2.png",
            "assets/avatars/kit/jump/r/3.png",
          ],
        },
      },
    },
    { name: "blocky",
      baseColor: [0x17, 0x7C, 0x69],  // the base color of the part that changes colors
      range: [0.4, 0.6],              // the hue range to adjust. Only hues in this range will be affected
      scale: 1,                       // Can be used to slightly scale a sprite that's too small
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,

      // for the animations:
      //   scale:  how much to scale UP the sprite using nearest neighbor
      //   slices: how large each slice is before it's scaled. Now this can also be an array
      //           in which case each entry is the width of a slice starting from the left.
      //   if slices is NOT specifed the entire file is just one frame.

      anims: {
        move: { url: "assets/avatars/blocky/blocky_walkright.png", scale: 2, slices: 16, },
        idle: { url: "assets/avatars/blocky/blocky_right.png",     scale: 2, slices: 16, },
        jump: { url: "assets/avatars/blocky/blocky_walkright.png", scale: 2, slices: 16, },
      },
    },
    { name: "miyamoto",
      baseColor: [0x8A, 0x56, 0x24],
      range: [0.078, 0.1],
      scale: 32/27,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.2,
      anims: {
        move: { url: "assets/avatars/miyamoto/run.png", scale: 1, slices: 20, },
        idle: { url: "assets/avatars/miyamoto/idle.png", },
        jump: { url: "assets/avatars/miyamoto/jump.png", scale: 1, slices: 19, },
      },
    },
    { name: "bird",
      baseColor: [0x00, 0x98, 0xCC],
      range: [180 / 360, 275 / 360],  // color range for colorizing duck but not beak
      scale: 1,
      idleAnimSpeed: 4,
      moveAnimSpeed: 0.1,
      anims: {
        idle:  { url: "assets/spr_idle.png",    scale: 2, slices: 16, },
        move:  { url: "assets/spr_run.png",     scale: 2, slices: 16, },
        jump:  { url: "assets/spr_jump.png",    scale: 2, slices: [16, 17, 17, 18, 16, 16] },
      },
    },
  ];

  avatars.forEach(function(avatar) {
    var c = avatar.baseColor;
    avatar.baseHSV = ImageUtils.rgbToHsv(c[0], c[1], c[2]);
  });

  return avatars;
});

<|endoftext|>


<commit_before>module.exports = GraphView

var fireflower = require('../../')
var NodeView = require('./node')
var isRetina = window.devicePixelRatio > 1

function GraphView (url, root) {
  this.url = url
  this.el = document.querySelector('.graph')
  this.nodesEl = this.el.querySelector('.nodes')
  this.canvas = this.el.querySelector('canvas')
  this.context = this.canvas.getContext('2d')
  this.nodes = {}

  this.root = new NodeView(this, root)
  this.root.el.classList.add('root')
  this.nodes[this.root.id] = this.root

  if (isRetina) {
    this.context.scale(2, 2)
  }

  this.nodesEl.addEventListener('click', this._onclick.bind(this))
  window.addEventListener('resize', this.render.bind(this))
}

GraphView.prototype.render = function () {
  this.width = window.innerWidth
  this.height = window.innerHeight

  this.canvas.width = isRetina ? this.width * 2 : this.width
  this.canvas.height = isRetina ? this.height * 2 : this.height
  this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)

  var root = this.root = this.nodes[this.root.id]
  root.x = this.width / 2
  root.y = this.height / 2

  for (var i in this.nodes) {
    var node = this.nodes[i]

    if (!node.el.parentNode) {
      this.nodesEl.appendChild(node.el)
    }

    node.render()
  }
}

GraphView.prototype.add = function () {
  var model = fireflower(this.url).connect()
  var node = new NodeView(this, model)
  this.nodes[node.id] = node
  return node
}

GraphView.prototype.remove = function (node) {
  delete this.nodes[node.id]
}

GraphView.prototype._onclick = function (evt) {
  if (evt.target !== this.nodesEl) return

  var node = this.add()
  node.x = evt.x
  node.y = evt.y

  this.render()
}
<commit_msg>example GraphView: remember to pass in external Firebase<commit_after>module.exports = GraphView

var fireflower = require('../../')(require('firebase'))
var NodeView = require('./node')
var isRetina = window.devicePixelRatio > 1

function GraphView (url, root) {
  this.url = url
  this.el = document.querySelector('.graph')
  this.nodesEl = this.el.querySelector('.nodes')
  this.canvas = this.el.querySelector('canvas')
  this.context = this.canvas.getContext('2d')
  this.nodes = {}

  this.root = new NodeView(this, root)
  this.root.el.classList.add('root')
  this.nodes[this.root.id] = this.root

  if (isRetina) {
    this.context.scale(2, 2)
  }

  this.nodesEl.addEventListener('click', this._onclick.bind(this))
  window.addEventListener('resize', this.render.bind(this))
}

GraphView.prototype.render = function () {
  this.width = window.innerWidth
  this.height = window.innerHeight

  this.canvas.width = isRetina ? this.width * 2 : this.width
  this.canvas.height = isRetina ? this.height * 2 : this.height
  this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)

  var root = this.root = this.nodes[this.root.id]
  root.x = this.width / 2
  root.y = this.height / 2

  for (var i in this.nodes) {
    var node = this.nodes[i]

    if (!node.el.parentNode) {
      this.nodesEl.appendChild(node.el)
    }

    node.render()
  }
}

GraphView.prototype.add = function () {
  var model = fireflower(this.url).connect()
  var node = new NodeView(this, model)
  this.nodes[node.id] = node
  return node
}

GraphView.prototype.remove = function (node) {
  delete this.nodes[node.id]
}

GraphView.prototype._onclick = function (evt) {
  if (evt.target !== this.nodesEl) return

  var node = this.add()
  node.x = evt.x
  node.y = evt.y

  this.render()
}
<|endoftext|>


<commit_before>import DateInfo, { addDays, getDayFromDate } from '@/utils/dateInfo';
import dayData from '../util/dayData.json';

describe('addDays', () => {
  it('should add days correctly', () => {
    const origin = new Date(2018, 0, 1);
    expect(addDays(origin, 1).valueOf()).toEqual((new Date(2018, 0, 2)).valueOf());
    expect(addDays(origin, 30).valueOf()).toEqual((new Date(2018, 0, 31)).valueOf());
    expect(addDays(origin, -1).valueOf()).toEqual((new Date(2017, 11, 31)).valueOf());
  });
});

describe('getDayFromDate', () => {
  it('should calculate day components correctly', () => {
    const testComponent = (c) => {
      const day = getDayFromDate(new Date(c.date));
      if (c.day !== day.day) return false;
      if (c.dayFromEnd !== day.dayFromEnd) return false;
      if (c.weekday !== day.weekday) return false;
      if (c.weekdayOrdinal !== day.weekdayOrdinal) return false;
      if (c.weekdayOrdinalFromEnd !== day.weekdayOrdinalFromEnd) return false;
      if (c.week !== day.week) return false;
      if (c.weekFromEnd !== day.weekFromEnd) return false;
      if (c.month !== day.month) return false;
      if (c.year !== day.year) return false;
      return true;
    };
    dayData.forEach(c => expect(testComponent(c)).toEqual(true));
  });
});

describe('DateInfo simple date', () => {
  const date = DateInfo(new Date(2018, 0, 1));
  it('should include simple date', () => {
    expect(date.includesDate(new Date(2018, 0, 1))).toEqual(true);
  });
  it('should not include simple dates', () => {
    expect(date.includesDate(new Date(2017, 11, 31))).toEqual(false);
    expect(date.includesDate(new Date(2018, 0, 2))).toEqual(false);
  });
  it('should include date range', () => {
    expect(date.includesDate(DateInfo({
      start: new Date(2018, 0, 1),
      end: new Date(2018, 0, 1),
    }))).toEqual(true);
  });
  it('should not include date ranges', () => {
    const ranges = [
      { start: new Date(2017, 11, 1), end: new Date(2017, 11, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 2) },
      { start: new Date(2018, 0, 2), end: new Date(2018, 0, 31) },
      { start: new Date(2017, 11, 1), end: new Date(2018, 0, 31) },
    ];
    ranges.forEach(r => expect(date.includesDate(DateInfo(r))).toEqual(false));
  });
});

describe('DateInfo date range', () => {
  const date = DateInfo({ start: new Date(2018, 0, 1), end: new Date(2018, 0, 15) });
  it('should include simple dates', () => {
    const dates = [new Date(2018, 0, 1), new Date(2018, 0, 10), new Date(2018, 0, 15)];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(true));
  });
  it('should not include simple dates', () => {
    const dates = [new Date(2017, 11, 31), new Date(2018, 0, 16)];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(false));
  });
  it('should include date ranges', () => {
    const dates = [
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 2) },
      { start: new Date(2018, 0, 2), end: new Date(2018, 0, 14) },
      { start: new Date(2018, 0, 14), end: new Date(2018, 0, 15) },
      { start: new Date(2018, 0, 15), end: new Date(2018, 0, 15) },
    ];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(true));
  });
  it('should not include date ranges', () => {
    const dates = [
      { start: new Date(2017, 11, 1), end: new Date(2017, 11, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 15), end: new Date(2018, 0, 16) },
      { start: new Date(2018, 0, 16), end: new Date(2018, 0, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 16) },
    ];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(false));
  });
});
<commit_msg>Inital test corrections<commit_after>import DateInfo, { addDays } from '@/utils/dateInfo';
import dayData from '../util/dayData.json';
import Locale from '../../../src/utils/locale.js';

describe('addDays', () => {
  it('should add days correctly', () => {
    const origin = new Date(2018, 0, 1);
    expect(addDays(origin, 1).valueOf()).toEqual(
      new Date(2018, 0, 2).valueOf(),
    );
    expect(addDays(origin, 30).valueOf()).toEqual(
      new Date(2018, 0, 31).valueOf(),
    );
    expect(addDays(origin, -1).valueOf()).toEqual(
      new Date(2017, 11, 31).valueOf(),
    );
  });
});

describe('getDayFromDate', () => {
  it('should calculate day components correctly', () => {
    const testComponent = c => {
      const day = getDayFromDate(new Date(c.date));
      if (c.day !== day.day) return false;
      if (c.dayFromEnd !== day.dayFromEnd) return false;
      if (c.weekday !== day.weekday) return false;
      if (c.weekdayOrdinal !== day.weekdayOrdinal) return false;
      if (c.weekdayOrdinalFromEnd !== day.weekdayOrdinalFromEnd) return false;
      if (c.week !== day.week) return false;
      if (c.weekFromEnd !== day.weekFromEnd) return false;
      if (c.month !== day.month) return false;
      if (c.year !== day.year) return false;
      return true;
    };
    dayData.forEach(c => expect(testComponent(c)).toEqual(true));
  });
});

describe('DateInfo simple date', () => {
  const locale = new Locale();
  const date = new DateInfo(new Date(2018, 0, 1), locale);
  it('should include simple date', () => {
    expect(date.includesDate(new Date(2018, 0, 1))).toEqual(true);
  });
  it('should not include simple dates', () => {
    expect(date.includesDate(new Date(2017, 11, 31))).toEqual(false);
    expect(date.includesDate(new Date(2018, 0, 2))).toEqual(false);
  });
  it('should include date range', () => {
    expect(
      date.includesDate(
        new DateInfo({
          start: new Date(2018, 0, 1),
          end: new Date(2018, 0, 1),
        }),
      ),
    ).toEqual(true);
  });
  it('should not include date ranges', () => {
    const ranges = [
      { start: new Date(2017, 11, 1), end: new Date(2017, 11, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 2) },
      { start: new Date(2018, 0, 2), end: new Date(2018, 0, 31) },
      { start: new Date(2017, 11, 1), end: new Date(2018, 0, 31) },
    ];
    ranges.forEach(r =>
      expect(date.includesDate(new DateInfo(r))).toEqual(false),
    );
  });
});

describe('DateInfo date range', () => {
  const date = new DateInfo({
    start: new Date(2018, 0, 1),
    end: new Date(2018, 0, 15),
  });
  it('should include simple dates', () => {
    const dates = [
      new Date(2018, 0, 1),
      new Date(2018, 0, 10),
      new Date(2018, 0, 15),
    ];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(true));
  });
  it('should not include simple dates', () => {
    const dates = [new Date(2017, 11, 31), new Date(2018, 0, 16)];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(false));
  });
  it('should include date ranges', () => {
    const dates = [
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 1), end: new Date(2018, 0, 2) },
      { start: new Date(2018, 0, 2), end: new Date(2018, 0, 14) },
      { start: new Date(2018, 0, 14), end: new Date(2018, 0, 15) },
      { start: new Date(2018, 0, 15), end: new Date(2018, 0, 15) },
    ];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(true));
  });
  it('should not include date ranges', () => {
    const dates = [
      { start: new Date(2017, 11, 1), end: new Date(2017, 11, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 1) },
      { start: new Date(2018, 0, 15), end: new Date(2018, 0, 16) },
      { start: new Date(2018, 0, 16), end: new Date(2018, 0, 31) },
      { start: new Date(2017, 11, 31), end: new Date(2018, 0, 16) },
    ];
    dates.forEach(d => expect(date.includesDate(d)).toEqual(false));
  });
});
<|endoftext|>


<commit_before>const fs = require('fs');
const EXAMPLE_IDENTIFIER = '.example';

const files = [
    'info.example.plist'
];

files.forEach(file => {
    fs.createReadStream(file).pipe(fs.createWriteStream(file.replace(EXAMPLE_IDENTIFIER, '')));
});
<commit_msg>Update script to delete previous file before copying new plist<commit_after>const fs = require('fs');
const EXAMPLE_IDENTIFIER = '.example';

const files = [
    'info.example.plist'
];

files.forEach(file => {
    const newFile = file.replace(EXAMPLE_IDENTIFIER, '');
    fs.unlink(newFile, () => {
        fs.createReadStream(file).pipe(fs.createWriteStream(newFile));
    });
});
<|endoftext|>


<commit_before>var request = require('request');
var cheerio = require('cheerio');
var url = require('url');
var iconv = require('iconv-lite');
var charsetDetector = require("node-icu-charset-detector");

module.exports = function(from, to, uri) {
    if (uri.length === 1) {
        uri = url.parse(uri[0]);
    }
    else {
        uri = url.parse(uri[1]);
    }
    var options = {
        url: uri.href,
        headers: {
            'User-Agent': 'request',
            'Cookie': 'over18=1',
            'Accept-Language': 'zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3'
        },
        timeout: 3000,
        gzip: true,
        encoding: null
    };
    request(options, function(error, response, body) {
        if (!error) {
            body = iconv.decode(body, charsetDetector.detectCharset(body));
            $ = cheerio.load(body);
            var title = $('title').text().trim().replace(/\s/g, ' ');
            if (title != '') {
                /*global oktw*/
                oktw.say(from, to, '[Title] ' + title);
            }
        }
    });
};

module.exports.info = {
    name: 'title',
    rawcommand: /https?:\/\/\S*/i
};
<commit_msg>fix encodeurl bug<commit_after>var request = require('request');
var cheerio = require('cheerio');
var url = require('url');
var iconv = require('iconv-lite');
var charsetDetector = require("node-icu-charset-detector");

module.exports = function(from, to, uri) {
    if (uri.length === 1) {
        uri = url.parse(uri[0]);
    }
    else {
        uri = url.parse(uri[1]);
    }
    var options = {
        url: encodeURI(decodeURIComponent(uri.href)),
        headers: {
            'User-Agent': 'request',
            'Cookie': 'over18=1',
            'Accept-Language': 'zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3'
        },
        timeout: 000,
        gzip: true,
        encoding: null
    };
    request(options, function(error, response, body) {
        if (!error) {
            body = iconv.decode(body, charsetDetector.detectCharset(body));
            $ = cheerio.load(body);
            var title = $('title').text().trim().replace(/\s/g, ' ');
            if (title != '') {
                /*global oktw*/
                oktw.say(from, to, '[Title] ' + title);
            }
        }
    });
};

module.exports.info = {
    name: 'title',
    rawcommand: /https?:\/\/\S*/i
};
<|endoftext|>


<commit_before>
var os = require("os");
var libui = require("../index.js");

var win = new libui.UiWindow("Test window", 800, 600, false);
win.margined = 1;
win.onClosing(function () {
	libui.stopLoop();
});

var box = new libui.UiVerticalBox();
var hBox = new libui.UiHorizontalBox();
var e1 = new libui.UiEntry();
e1.enabled = 0;
hBox.append(new libui.UiLabel("ciao"), false);
hBox.append(e1, false);

box.append(new libui.UiEntry(), false);
box.append(hBox, false);

if (os.platform() !== "darwin") {
	box.append(new libui.UiSearchEntry(), false);
}

box.append(new libui.UiPasswordEntry(), false);

var cmb = new libui.UiCombobox();

cmb.append("item 1");
cmb.append("item 2");
cmb.append("item 3");

box.append(cmb, false);
var hBox4 = new libui.UiHorizontalBox();
hBox4.append(new libui.UiDateTimePicker(), false);
hBox4.append(new libui.UiVerticalSeparator(), false);
hBox4.append(new libui.UiEditableCombobox(), false);
hBox4.append(new libui.UiCheckbox("Optionally"), false);

box.append(hBox4, false);

var group = new libui.UiGroup("Options");
var radios = new libui.UiRadioButtons();
radios.append("option 1");
radios.append("option 2");
radios.append("option 3");

group.setChild(radios);
box.append(group, true);

box.append(new libui.UiHorizontalSeparator(), true);

var hBox2 = new libui.UiHorizontalBox();
var spin = new libui.UiSpinbox(0, 100);
spin.value = 33;
hBox2.append(new libui.UiLabel("Number"), false);
hBox2.append(spin, true);
box.append(hBox2, false);

var hBox3 = new libui.UiHorizontalBox();
var slider = new libui.UiSlider(0, 100);
slider.value = 33;
hBox3.append(new libui.UiLabel("Number"), false);
hBox3.append(slider, false);
box.append(hBox3, false);

box.append(new libui.UiMultilineEntry(), false);

var buttons = new libui.UiHorizontalBox();
buttons.append(new libui.UiButton("Ok"), false);
buttons.append(new libui.UiButton("Maybe"), false);
buttons.append(new libui.UiButton("Cancel"), false);

box.append(new libui.UiProgressBar(), false);
box.append(new libui.UiFontButton(), false);

box.append(buttons, false);

var tabs = new libui.UiTab();

tabs.append("controls", box);
tabs.append("text", new libui.UiMultilineEntry());

win.setChild(tabs);

win.show();
libui.startLoop();
<commit_msg>core api example: add interval and http server to test node event loop integration<commit_after>
var os = require("os");
var libui = require("../index.js");

var win = new libui.UiWindow("Test window", 800, 600, false);
win.margined = 1;
win.onClosing(function () {
	libui.stopLoop();
});

var box = new libui.UiVerticalBox();
var hBox = new libui.UiHorizontalBox();
var e1 = new libui.UiEntry();
e1.enabled = 0;
var lblCiao = new libui.UiLabel("ciao");
hBox.append(lblCiao, false);
hBox.append(e1, false);
let idxLbl = 0;
setInterval(() => {
	lblCiao.text = String(idxLbl++);
}, 1000);
const http = require('http');
const net = require('net');
const url = require('url');

// Create an HTTP tunneling proxy
const proxy = http.createServer((req, res) => {
  lblCiao.text = String(idxLbl++);
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(String(idxLbl));
});
proxy.listen(3000, '127.0.0.1', () => {
	console.log('listening...');
});

box.append(new libui.UiEntry(), false);
box.append(hBox, false);

if (os.platform() !== "darwin") {
	box.append(new libui.UiSearchEntry(), false);
}

box.append(new libui.UiPasswordEntry(), false);

var cmb = new libui.UiCombobox();

cmb.append("item 1");
cmb.append("item 2");
cmb.append("item 3");

box.append(cmb, false);
var hBox4 = new libui.UiHorizontalBox();
hBox4.append(new libui.UiDateTimePicker(), false);
hBox4.append(new libui.UiVerticalSeparator(), false);
hBox4.append(new libui.UiEditableCombobox(), false);
hBox4.append(new libui.UiCheckbox("Optionally"), false);

box.append(hBox4, false);

var group = new libui.UiGroup("Options");
var radios = new libui.UiRadioButtons();
radios.append("option 1");
radios.append("option 2");
radios.append("option 3");

group.setChild(radios);
box.append(group, true);

box.append(new libui.UiHorizontalSeparator(), true);

var hBox2 = new libui.UiHorizontalBox();
var spin = new libui.UiSpinbox(0, 100);
spin.value = 33;
hBox2.append(new libui.UiLabel("Number"), false);
hBox2.append(spin, true);
box.append(hBox2, false);

var hBox3 = new libui.UiHorizontalBox();
var slider = new libui.UiSlider(0, 100);
slider.value = 33;
hBox3.append(new libui.UiLabel("Number"), false);
hBox3.append(slider, false);
box.append(hBox3, false);

box.append(new libui.UiMultilineEntry(), false);

var buttons = new libui.UiHorizontalBox();
buttons.append(new libui.UiButton("Ok"), false);
buttons.append(new libui.UiButton("Maybe"), false);
buttons.append(new libui.UiButton("Cancel"), false);

box.append(new libui.UiProgressBar(), false);
box.append(new libui.UiFontButton(), false);

box.append(buttons, false);

var tabs = new libui.UiTab();

tabs.append("controls", box);
tabs.append("text", new libui.UiMultilineEntry());

win.setChild(tabs);

win.show();
libui.startLoop();
<|endoftext|>


<commit_before>"use strict";
define(['text!templates/user/registerView.html',
		'../models/User'],
		function(templateData,model){
	return Backbone.View.extend({
		model:model,
		events:{
			"submit .create-account-form"  	:  "createAccount",
			"click .go-to-login"  			:  "gotoLogin"
		},
		validate:function(){
			$(this.el).find('.create-account-form').validate({
				debug: true,
				rules:{
					repeatPassword: {
						equalTo : "#inputPassword"
					}
				},
				messages:{
					repeatPassword: {
						equalTo : openbiz.apps.cubi.locale.registerView.validation.passwordNotMatch
					}
				}
			});

		},
		createAccount:function(event)
		{
			if(!$(this.el).find('.create-account-form').valid())return;
			var userRecord = {
				username: $(this.el).find('#inputEmail').val(),
				password: $(this.el).find('#inputPassword').val()
			}
			console.log('Create Account');
			console.log(userRecord);
		},
		gotoLogin:function()
		{
			event.preventDefault();
			var self=this;
			$(this.el).find('.go-to-login').replaceWith(openbiz.apps.cubi.locale.loading);
			openbiz.apps.cubi.require(['./modules/user/views/LoginView'],function(forgetPasswordView){
				var view = new forgetPasswordView();
				$(self.el).fadeOut(function(){
					$(self.el).html(view.render().el).fadeIn();
				})
			})
		},
		initialize:function(){
	        this.template = _.template(templateData);
    	},
		render:function(){
	        $(this.el).html(this.template(openbiz.apps.cubi.locale.registerView));
	        this.localize();
	        this.validate();
	        return this;
	    },
	    localize:function(){
	    	var nameElems = {
	    		firstName : $(this.el).find('#inputFirstName'),
	    		lastName : $(this.el).find('#inputLastName')
	    	}
	    	var nameRootElem = nameElems.firstName.parent();
	    	nameRootElem.html('');
	    	for(var i in openbiz.apps.cubi.locale.registerView.nameFormat){
	    		var elem = nameElems[openbiz.apps.cubi.locale.registerView.nameFormat[i]];
	    		switch(parseInt(i))
	    		{
	    			case 0:
	    				elem.css({'width':'47%','margin-right':'3%'});
	    				break;
	    			case 1:
	    				elem.css({'width':'50%','margin-right':'0%'});
	    				break;
	    		}
	    		nameRootElem.append(elem);

	    	}

	    }
	});
})<commit_msg>update<commit_after>"use strict";
define(['text!templates/user/registerView.html',
		'../models/User'],
		function(templateData,model){
	return Backbone.View.extend({
		model:model,
		events:{
			"submit .create-account-form"  	:  "createAccount",
			"click .go-to-login"  			:  "gotoLogin"
		},
		validate:function(){
			$(this.el).find('.create-account-form').validate({
				debug: true,
				rules:{
					mobileNumber:{
						number:true
					},
					repeatPassword: {
						equalTo : "#inputPassword"
					}
				},
				messages:{
					repeatPassword: {
						equalTo : openbiz.apps.cubi.locale.registerView.validation.passwordNotMatch
					}
				}
			});

		},
		createAccount:function(event)
		{
			if(!$(this.el).find('.create-account-form').valid())return;
			if(openbiz.apps.cubi.locale.registerView.nameFormat[0]=='firstName'){
				var displayName = $(this.el).find('#inputLastName').val() + $(this.el).find('#inputFirstName').val();
			}else{
				var displayName = $(this.el).find('#inputLastName').val() + $(this.el).find('#inputFirstName').val();
			}
			var userRecord = {
				username: $(this.el).find('#inputEmail').val(),
				password: $(this.el).find('#inputPassword').val(),
				contact:{
					name:{
						firstName: 		$(this.el).find('#inputFirstName').val(),
						lastName: 		$(this.el).find('#inputLastName').val(),
						displayName: 	displayName
					},
					company: $(this.el).find('#inputCompany').val(),
					title:   $(this.el).find('input:radio[name="title"]#title-mr').is(":checked")?'Mr.':'Ms.',
					emails:[{
						category: 	'Default',
						email: 		$(this.el).find('#inputEmail').val()
					}],
					phones:[{
						type: 		'mobile',
						category: 	'Default',
						countryCode:$(this.el).find('#inputMobileCountryCode').val(),
						number: 	$(this.el).find('#inputMobileNumber').val(),
					}]
				}
			}
			console.log('Create Account');
			console.log(userRecord);
		},
		gotoLogin:function()
		{
			event.preventDefault();
			var self=this;
			$(this.el).find('.go-to-login').replaceWith(openbiz.apps.cubi.locale.loading);
			openbiz.apps.cubi.require(['./modules/user/views/LoginView'],function(forgetPasswordView){
				var view = new forgetPasswordView();
				$(self.el).fadeOut(function(){
					$(self.el).html(view.render().el).fadeIn();
				})
			})
		},
		initialize:function(){
	        this.template = _.template(templateData);
    	},
		render:function(){
	        $(this.el).html(this.template(openbiz.apps.cubi.locale.registerView));
	        this.localize();
	        this.validate();
	        return this;
	    },
	    localize:function(){
	    	var nameElems = {
	    		firstName : $(this.el).find('#inputFirstName'),
	    		lastName : $(this.el).find('#inputLastName')
	    	}
	    	var nameRootElem = nameElems.firstName.parent();
	    	nameRootElem.html('');
	    	for(var i in openbiz.apps.cubi.locale.registerView.nameFormat){
	    		var elem = nameElems[openbiz.apps.cubi.locale.registerView.nameFormat[i]];
	    		switch(parseInt(i))
	    		{
	    			case 0:
	    				elem.css({'width':'47%','margin-right':'3%'});
	    				break;
	    			case 1:
	    				elem.css({'width':'50%','margin-right':'0%'});
	    				break;
	    		}
	    		nameRootElem.append(elem);

	    	}

	    }
	});
})<|endoftext|>


<commit_before>#!/usr/local/bin/node

var fs = require("fs"),
  version = process.env["npm.package.version"],
  bin = "/usr/local/bin/npm-"+version,
  clijs = require("path").join(process.cwd(), "cli.js"),
  sys = require("sys");

fs.lstat(bin, function (er, st) {
  if (!er) fs.unlink(bin, linkBin);
  else linkBin();
});

function linkBin (er) {
  if (er) throw er;
  sys.puts("about to link " + clijs+" to " +bin);
  fs.symlinkSync(clijs, bin, function (er) {
    if (er) throw er;
  });
}
<commit_msg>Remove debug code<commit_after>#!/usr/local/bin/node

var fs = require("fs"),
  version = process.env["npm.package.version"],
  bin = "/usr/local/bin/npm-"+version,
  clijs = require("path").join(process.cwd(), "cli.js"),
  sys = require("sys");

fs.lstat(bin, function (er, st) {
  if (!er) fs.unlink(bin, linkBin);
  else linkBin();
});

function linkBin (er) {
  if (er) throw er;
  fs.symlinkSync(clijs, bin, function (er) {
    if (er) throw er;
  });
}
<|endoftext|>


<commit_before>import { assertThat, not, greaterThan } from 'hamjest';
import {
  buildFunctionSpy,
  wasCalled, wasCalledWith,
  wasNotCalled, callCountWas,
  firstCallArgsWere, lastCallArgsWere,
} from './index';

describe('Matchers:', () => {
  describe('`wasCalled()`', () => {
    it('passes when spied-on function got called', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, wasCalled());
    });
    it('bails when spied-on function had NOT been called', () => {
      const f = buildFunctionSpy();
      assertThat(f, not(wasCalled()));
    });
  });

  describe('`wasCalledWith()`', () => {
    it('passes when spied-on function got called', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, wasCalledWith());
    });
    it('passes when spied-on function got called with expected first arg', () => {
      const f = buildFunctionSpy();
      f(42);
      assertThat(f, wasCalledWith(42));
    });
    describe('fails when the spied-on-function', () => {
      it('was not called', () => {
        const f = buildFunctionSpy();
        assertThat(f, not(wasCalledWith()));
      });
      it('was not called with expected args', () => {
        const f = buildFunctionSpy();
        f();
        assertThat(f, not(wasCalledWith(23)));
      });
      it('was not called with the expected 2nd arg', () => {
        const f = buildFunctionSpy();
        f(1);
        assertThat(f, not(wasCalledWith(1, 2)));
      });
    });
  });

  describe('`wasNotCalled()`', () => {
    it('fires when spied-on function was NOT called', () => {
      const f = buildFunctionSpy();
      assertThat(f, wasNotCalled());
    });
    it('bails when spied-on function was called', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, not(wasNotCalled()));
    });
  });

  describe('`firstCallArgsWere()`', () => {
    it('passes when spy was called with expected args', () => {
      const firstArgument = '1';
      const f = buildFunctionSpy();
      f(firstArgument);
      assertThat(f, firstCallArgsWere([firstArgument]));
    });
    it('fails when spy was called with more args', () => {
      const firstArgument = '1';
      const f = buildFunctionSpy();
      f(firstArgument, 'unexpected 2nd arg');
      assertThat(f, not(firstCallArgsWere([firstArgument])));
    });
    it('fails when spy was called without args', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, not(firstCallArgsWere(['expected arg'])));
    });
  });

  describe('`lastCallArgsWere()`', () => {
    it('passes when last call`s args match', () => {
      const args = [1, 'two'];
      const f = buildFunctionSpy();

      f(args[0], args[1]);

      assertThat(f, lastCallArgsWere(args));
    });
    it('passes even when other args were used before', () => {
      const args = [1, 'two'];
      const f = buildFunctionSpy();

      f();                  // first call
      f(args[0], args[1]);  // last call

      assertThat(f, lastCallArgsWere(args));
    });
    it('bails when args don`t match', () => {
      const args = [];
      const f = buildFunctionSpy();

      f(1, 'two');

      assertThat(f, not(lastCallArgsWere(args)));
    });
  });

  describe('`callCountWas()`', () => {
    it('passes when spy got called once', () => {
      const f = buildFunctionSpy();

      f();

      assertThat(f, callCountWas(1));
    });
    it('passes for multiple calls', () => {
      const f = buildFunctionSpy();

      f();
      f();
      f();

      assertThat(f, callCountWas(3));
    });
  });
});

// more:
// - when NOT to use a matcher
// - how to use the spy, e.g. with returnValue
// - how to use it inside a class or as property
<commit_msg>Group passing tests, and extend the one that tests many args.<commit_after>import { assertThat, not, greaterThan } from 'hamjest';
import {
  buildFunctionSpy,
  wasCalled, wasCalledWith,
  wasNotCalled, callCountWas,
  firstCallArgsWere, lastCallArgsWere,
} from './index';

describe('Matchers:', () => {
  describe('`wasCalled()`', () => {
    it('passes when spied-on function got called', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, wasCalled());
    });
    it('bails when spied-on function had NOT been called', () => {
      const f = buildFunctionSpy();
      assertThat(f, not(wasCalled()));
    });
  });

  describe('`wasCalledWith()`', () => {
    describe('passes when spied-on function', () => {
      it('got called', () => {
        const f = buildFunctionSpy();
        f();
        assertThat(f, wasCalledWith());
      });
      it('got called with expected arg', () => {
        const f = buildFunctionSpy();
        f(23, 42, {a: 1}, [0, 1]);
        assertThat(f, wasCalledWith(23, 42, {a: 1}, [0, 1]));
      });
    });
    describe('fails when the spied-on-function', () => {
      it('was not called', () => {
        const f = buildFunctionSpy();
        assertThat(f, not(wasCalledWith()));
      });
      it('was not called with expected args', () => {
        const f = buildFunctionSpy();
        f();
        assertThat(f, not(wasCalledWith(23)));
      });
      it('was not called with the expected 2nd arg', () => {
        const f = buildFunctionSpy();
        f(1);
        assertThat(f, not(wasCalledWith(1, 2)));
      });
    });
  });

  describe('`wasNotCalled()`', () => {
    it('fires when spied-on function was NOT called', () => {
      const f = buildFunctionSpy();
      assertThat(f, wasNotCalled());
    });
    it('bails when spied-on function was called', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, not(wasNotCalled()));
    });
  });

  describe('`firstCallArgsWere()`', () => {
    it('passes when spy was called with expected args', () => {
      const firstArgument = '1';
      const f = buildFunctionSpy();
      f(firstArgument);
      assertThat(f, firstCallArgsWere([firstArgument]));
    });
    it('fails when spy was called with more args', () => {
      const firstArgument = '1';
      const f = buildFunctionSpy();
      f(firstArgument, 'unexpected 2nd arg');
      assertThat(f, not(firstCallArgsWere([firstArgument])));
    });
    it('fails when spy was called without args', () => {
      const f = buildFunctionSpy();
      f();
      assertThat(f, not(firstCallArgsWere(['expected arg'])));
    });
  });

  describe('`lastCallArgsWere()`', () => {
    it('passes when last call`s args match', () => {
      const args = [1, 'two'];
      const f = buildFunctionSpy();

      f(args[0], args[1]);

      assertThat(f, lastCallArgsWere(args));
    });
    it('passes even when other args were used before', () => {
      const args = [1, 'two'];
      const f = buildFunctionSpy();

      f();                  // first call
      f(args[0], args[1]);  // last call

      assertThat(f, lastCallArgsWere(args));
    });
    it('bails when args don`t match', () => {
      const args = [];
      const f = buildFunctionSpy();

      f(1, 'two');

      assertThat(f, not(lastCallArgsWere(args)));
    });
  });

  describe('`callCountWas()`', () => {
    it('passes when spy got called once', () => {
      const f = buildFunctionSpy();

      f();

      assertThat(f, callCountWas(1));
    });
    it('passes for multiple calls', () => {
      const f = buildFunctionSpy();

      f();
      f();
      f();

      assertThat(f, callCountWas(3));
    });
  });
});

// more:
// - when NOT to use a matcher
// - how to use the spy, e.g. with returnValue
// - how to use it inside a class or as property
<|endoftext|>


<commit_before><commit_msg>Adding missing Address2 functionality for data-attr<commit_after><|endoftext|>


<commit_before>import { Vector3 } from './Vector3';

/**
 * @author alteredq / http://alteredqualia.com/
 * @author WestLangley / http://github.com/WestLangley
 * @author bhouston / http://clara.io
 * @author tschw
 */

function Matrix3() {

	this.elements = new Float32Array( [

		1, 0, 0,
		0, 1, 0,
		0, 0, 1

	] );

	if ( arguments.length > 0 ) {

		console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );

	}

}

Object.assign( Matrix3.prototype, {

	constructor: Matrix3,

	isMatrix3: true,

	set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {

		var te = this.elements;

		te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
		te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
		te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;

		return this;

	},

	identity: function () {

		this.set(

			1, 0, 0,
			0, 1, 0,
			0, 0, 1

		);

		return this;

	},

	clone: function () {

		return new this.constructor().fromArray( this.elements );

	},

	copy: function ( m ) {

		var me = m.elements;

		this.set(

			me[ 0 ], me[ 3 ], me[ 6 ],
			me[ 1 ], me[ 4 ], me[ 7 ],
			me[ 2 ], me[ 5 ], me[ 8 ]

		);

		return this;

	},

	setFromMatrix4: function( m ) {

		var me = m.elements;

		this.set(

			me[ 0 ], me[ 4 ], me[  8 ],
			me[ 1 ], me[ 5 ], me[  9 ],
			me[ 2 ], me[ 6 ], me[ 10 ]

		);

		return this;

	},

	applyToBufferAttribute: function () {

		var v1;

		return function applyToBufferAttribute( attribute ) {

			if ( v1 === undefined ) v1 = new Vector3();

			for ( var i = 0, l = attribute.count; i < l; i ++ ) {

				v1.x = attribute.getX( i );
				v1.y = attribute.getY( i );
				v1.z = attribute.getZ( i );

				v1.applyMatrix3( this );

				attribute.setXYZ( i, v1.x, v1.y, v1.z );

			}

			return attribute;

		};

	}(),

	multiplyScalar: function ( s ) {

		var te = this.elements;

		te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
		te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
		te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;

		return this;

	},

	determinant: function () {

		var te = this.elements;

		var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
			d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
			g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];

		return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;

	},

	getInverse: function ( matrix, throwOnDegenerate ) {

		if ( matrix && matrix.isMatrix4 ) {

			console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );

		}

		var me = matrix.elements,
			te = this.elements,

			n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
			n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
			n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],

			t11 = n33 * n22 - n32 * n23,
			t12 = n32 * n13 - n33 * n12,
			t13 = n23 * n12 - n22 * n13,

			det = n11 * t11 + n21 * t12 + n31 * t13;

		if ( det === 0 ) {

			var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";

			if ( throwOnDegenerate === true ) {

				throw new Error( msg );

			} else {

				console.warn( msg );

			}

			return this.identity();
		}

		var detInv = 1 / det;

		te[ 0 ] = t11 * detInv;
		te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
		te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;

		te[ 3 ] = t12 * detInv;
		te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
		te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;

		te[ 6 ] = t13 * detInv;
		te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
		te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;

		return this;

	},

	transpose: function () {

		var tmp, m = this.elements;

		tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
		tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
		tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;

		return this;

	},

	getNormalMatrix: function ( matrix4 ) {

		return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();

	},

	transposeIntoArray: function ( r ) {

		var m = this.elements;

		r[ 0 ] = m[ 0 ];
		r[ 1 ] = m[ 3 ];
		r[ 2 ] = m[ 6 ];
		r[ 3 ] = m[ 1 ];
		r[ 4 ] = m[ 4 ];
		r[ 5 ] = m[ 7 ];
		r[ 6 ] = m[ 2 ];
		r[ 7 ] = m[ 5 ];
		r[ 8 ] = m[ 8 ];

		return this;

	},

	fromArray: function ( array, offset ) {

		if ( offset === undefined ) offset = 0;

		for( var i = 0; i < 9; i ++ ) {

			this.elements[ i ] = array[ i + offset ];

		}

		return this;

	},

	toArray: function ( array, offset ) {

		if ( array === undefined ) array = [];
		if ( offset === undefined ) offset = 0;

		var te = this.elements;

		array[ offset ] = te[ 0 ];
		array[ offset + 1 ] = te[ 1 ];
		array[ offset + 2 ] = te[ 2 ];

		array[ offset + 3 ] = te[ 3 ];
		array[ offset + 4 ] = te[ 4 ];
		array[ offset + 5 ] = te[ 5 ];

		array[ offset + 6 ] = te[ 6 ];
		array[ offset + 7 ] = te[ 7 ];
		array[ offset + 8 ]  = te[ 8 ];

		return array;

	}

} );

export { Matrix3 };
<commit_msg>Improve Matrix3 closure performance<commit_after>import { Vector3 } from './Vector3';

/**
 * @author alteredq / http://alteredqualia.com/
 * @author WestLangley / http://github.com/WestLangley
 * @author bhouston / http://clara.io
 * @author tschw
 */

function Matrix3() {

	this.elements = new Float32Array( [

		1, 0, 0,
		0, 1, 0,
		0, 0, 1

	] );

	if ( arguments.length > 0 ) {

		console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );

	}

}

Object.assign( Matrix3.prototype, {

	constructor: Matrix3,

	isMatrix3: true,

	set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {

		var te = this.elements;

		te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
		te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
		te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;

		return this;

	},

	identity: function () {

		this.set(

			1, 0, 0,
			0, 1, 0,
			0, 0, 1

		);

		return this;

	},

	clone: function () {

		return new this.constructor().fromArray( this.elements );

	},

	copy: function ( m ) {

		var me = m.elements;

		this.set(

			me[ 0 ], me[ 3 ], me[ 6 ],
			me[ 1 ], me[ 4 ], me[ 7 ],
			me[ 2 ], me[ 5 ], me[ 8 ]

		);

		return this;

	},

	setFromMatrix4: function( m ) {

		var me = m.elements;

		this.set(

			me[ 0 ], me[ 4 ], me[  8 ],
			me[ 1 ], me[ 5 ], me[  9 ],
			me[ 2 ], me[ 6 ], me[ 10 ]

		);

		return this;

	},

	applyToBufferAttribute: function () {

		var v1 = new Vector3();

		return function applyToBufferAttribute( attribute ) {

			for ( var i = 0, l = attribute.count; i < l; i ++ ) {

				v1.x = attribute.getX( i );
				v1.y = attribute.getY( i );
				v1.z = attribute.getZ( i );

				v1.applyMatrix3( this );

				attribute.setXYZ( i, v1.x, v1.y, v1.z );

			}

			return attribute;

		};

	}(),

	multiplyScalar: function ( s ) {

		var te = this.elements;

		te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
		te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
		te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;

		return this;

	},

	determinant: function () {

		var te = this.elements;

		var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
			d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
			g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];

		return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;

	},

	getInverse: function ( matrix, throwOnDegenerate ) {

		if ( matrix && matrix.isMatrix4 ) {

			console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." );

		}

		var me = matrix.elements,
			te = this.elements,

			n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
			n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
			n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],

			t11 = n33 * n22 - n32 * n23,
			t12 = n32 * n13 - n33 * n12,
			t13 = n23 * n12 - n22 * n13,

			det = n11 * t11 + n21 * t12 + n31 * t13;

		if ( det === 0 ) {

			var msg = "THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0";

			if ( throwOnDegenerate === true ) {

				throw new Error( msg );

			} else {

				console.warn( msg );

			}

			return this.identity();
		}

		var detInv = 1 / det;

		te[ 0 ] = t11 * detInv;
		te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
		te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;

		te[ 3 ] = t12 * detInv;
		te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
		te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;

		te[ 6 ] = t13 * detInv;
		te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
		te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;

		return this;

	},

	transpose: function () {

		var tmp, m = this.elements;

		tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
		tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
		tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;

		return this;

	},

	getNormalMatrix: function ( matrix4 ) {

		return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();

	},

	transposeIntoArray: function ( r ) {

		var m = this.elements;

		r[ 0 ] = m[ 0 ];
		r[ 1 ] = m[ 3 ];
		r[ 2 ] = m[ 6 ];
		r[ 3 ] = m[ 1 ];
		r[ 4 ] = m[ 4 ];
		r[ 5 ] = m[ 7 ];
		r[ 6 ] = m[ 2 ];
		r[ 7 ] = m[ 5 ];
		r[ 8 ] = m[ 8 ];

		return this;

	},

	fromArray: function ( array, offset ) {

		if ( offset === undefined ) offset = 0;

		for( var i = 0; i < 9; i ++ ) {

			this.elements[ i ] = array[ i + offset ];

		}

		return this;

	},

	toArray: function ( array, offset ) {

		if ( array === undefined ) array = [];
		if ( offset === undefined ) offset = 0;

		var te = this.elements;

		array[ offset ] = te[ 0 ];
		array[ offset + 1 ] = te[ 1 ];
		array[ offset + 2 ] = te[ 2 ];

		array[ offset + 3 ] = te[ 3 ];
		array[ offset + 4 ] = te[ 4 ];
		array[ offset + 5 ] = te[ 5 ];

		array[ offset + 6 ] = te[ 6 ];
		array[ offset + 7 ] = te[ 7 ];
		array[ offset + 8 ]  = te[ 8 ];

		return array;

	}

} );

export { Matrix3 };
<|endoftext|>


<commit_before>var carrot2 = require('../lib/carrot2');

// Create DCS server in debug mode
var dcs = new carrot2.DocumentClusteringServer( {debug:true} );

dcs.externalCall(
	"seattle",
	{source:"bing-web"},
	[ {key:"LingoClusteringAlgorithm.desiredClusterCountBase", value:20} ],
	function(err, sr) {
		if(err) console.error(err);
		console.log(sr);
	}
);<commit_msg>removing old test example<commit_after>var carrot2 = require('../lib/carrot2');

// Create DCS server object in debug mode
var dcs = new carrot2.DocumentClusteringServer( {debug:true} );

//
dcs.externalCall(
	"seattle",
	{source:"bing-web"},
	[ {key:"LingoClusteringAlgorithm.desiredClusterCountBase", value:20} ],
	function(err, sr) {
		if(err) console.error(err);
		console.log(sr);
	}
);<|endoftext|>


<commit_before><commit_msg>whoops, deleted too much<commit_after><|endoftext|>


<commit_before>/**
 * Migration from Oregon to Singapore
 * with some minor changes in schems
 */
var async = require('async');
var AWS = require('aws-sdk');
/*
AWS.config.update({
  region: 'ap-southeast-1'
});
*/

var sourceDDB = new AWS.DynamoDB({
  region: 'us-west-2'
});

var destDDB = new AWS.DynamoDB({
  region: 'ap-southeast-1'
});

var lastEvaluatedKey = false;
var count = 0;
/*
async.doWhilst(function (callback) {
  var scanParams = {
    TableName: 'taxisg.locations'
  };

  if (lastEvaluatedKey) {
    scanParams.ExclusiveStartKey = lastEvaluatedKey;
  }

  sourceDDB.scan(scanParams, function (err, data) {
    if (err) {
      if (err.retryable === true) {
        console.log('Retryable error');
        return callback(null); // to retry
      } else {
        return callback(err);
      }
    }

    if (data.LastEvaluatedKey) {
      lastEvaluatedKey = data.LastEvaluatedKey;
    } else {
      lastEvaluatedKey = false;
    }

    // Save
    count = count + data.Count;
    console.log(count + ' rows migrated.');

    if (lastEvaluatedKey) {
      console.log('Last key: ' + lastEvaluatedKey.timestamp.N);
    } else {
      console.log('DONE');
    }

    return callback(null);
  });
}, function () {
  return lastEvaluatedKey;
}, function (err) {
  if (err) {
    console.log('Halted');
    return console.log(err);
  } else {
    return console.log('Completed successfully. Final count: ' + count);
  }
});
*/

migrate({
  timestamp: 2325,
  locations: [
    { asdf: 'pppppp' },
    { fpppff: 'sssssss' }
  ],
  count: 5
});

function migrate(row) {
  var docClient = new AWS.DynamoDB.DocumentClient({
    service: destDDB
  });
  var grainsTable = 'testsg.grains';
  var locationsTable = 'testsg.locations';

  async.series({
    validate: function (callback) {
      var params = {
        TableName: locationsTable,
        Select: 'COUNT',
        KeyConditionExpression: "#ts = :tttt",
        ExpressionAttributeNames: {
          '#ts': 'timestamp'
        },
        ExpressionAttributeValues: {
          ":tttt": row.timestamp
        }
      };

      docClient.query(params, function (err, data) {
        if (!err) {
          if (data.Count === 0) {
          } else {
            return callback('Data for timestamp ' + row.timestamp + ' is already logged.');
          }
        }
        return callback(err);
      });

    },

    put: function (callback) {
      var params = {
        TableName: locationsTable,
        Item: {
          timestamp: row.timestamp,
          locations: row.locations
        }
      };

      var saved = false;
      async.whilst( function() {
          return !saved;
        }, function (callback) {
        docClient.put(params, function (err, data) {
          saved = true;
          if (err && err.retryable === true) {
            saved = false;
          }
          callback(err);
        });
      }, function (err, data) {
        return callback(err);
      });
    },

    /**
     * Write to another table for sortability
     */
    grains: function (callback) {
      var params = {
        TableName: grainsTable,
        Item: {
          domain: 1,
          timestamp: row.timestamp,
          count: row.count
        }
      };

      var saved = false;
      async.whilst( function() {
          return !saved;
        }, function (callback) {
        docClient.put(params, function (err, data) {
          saved = true;
          if (err && err.retryable === true) {
            saved = false;
          }
          callback(err);
        });
      }, function (err, data) {
        return callback(err);
      });
    },
  }, function (err) {
    if (err) {
      return console.log(err);
    } else {
      console.log(row.locations);
      return console.log(row.count + ' (' + row.locations.length + ') locations saved successfully with timestamp ' + row.timestamp);
    }
  });
}
<commit_msg>Migrate done.<commit_after>/**
 * Migration from Oregon to Singapore
 * with some minor changes in schems
 */
var async = require('async');
var AWS = require('aws-sdk');
/*
AWS.config.update({
  region: 'ap-southeast-1'
});
*/

var sourceDDB = new AWS.DynamoDB({
  region: 'us-west-2'
});

var destDDB = new AWS.DynamoDB({
  region: 'ap-southeast-1'
});

var lastEvaluatedKey = false;
var count = 0;

async.doWhilst(function (callback) {
  var sourceClient = new AWS.DynamoDB.DocumentClient({
    service: sourceDDB
  });

  var scanParams = {
    TableName: 'taxisg.locations'
  };

  if (lastEvaluatedKey) {
    scanParams.ExclusiveStartKey = lastEvaluatedKey;
  }

  console.log('');
  console.log('[ Scanning next batch from ' + lastEvaluatedKey.timestamp + '... ]');

  sourceClient.scan(scanParams, function (err, data) {
    if (err) {
      if (err.retryable === true) {
        console.log('Retryable error');
        return callback(null); // to retry
      } else {
        return callback(err);
      }
    }

    if (data.LastEvaluatedKey) {
      lastEvaluatedKey = data.LastEvaluatedKey;
    } else {
      lastEvaluatedKey = false;
    }

    // Save
    count = count + data.Count;
    console.log(count + ' rows migrated.');

    async.each(data.Items, function (row, eachCb) {
      migrate(row, eachCb);
    }, function (err) {
      if (err) {
        console.log('Error at async.each encountered.');
        return console.log(err);
      }

      if (lastEvaluatedKey) {
        console.log('Last key: ' + lastEvaluatedKey.timestamp);
      } else {
        console.log('DONE');
      }

      return callback(null);
    });
  });
}, function () {
  return lastEvaluatedKey;
}, function (err) {
  if (err) {
    console.log('Halted');
    return console.log(err);
  } else {
    return console.log('Completed successfully. Final count: ' + count);
  }
});

/*
migrate({
  timestamp: 2325,
  locations: [
    { asdf: 'pppppp' },
    { fpppff: 'sssssss' }
  ],
  count: 5
});
*/

function migrate(row, next) {
  var docClient = new AWS.DynamoDB.DocumentClient({
    service: destDDB
  });
  var grainsTable = 'testsg.grains';
  var locationsTable = 'testsg.locations';

  async.series({
    validate: function (callback) {
      var params = {
        TableName: locationsTable,
        Select: 'COUNT',
        KeyConditionExpression: "#ts = :tttt",
        ExpressionAttributeNames: {
          '#ts': 'timestamp'
        },
        ExpressionAttributeValues: {
          ":tttt": row.timestamp
        }
      };

      docClient.query(params, function (err, data) {
        if (!err) {
          if (data.Count === 0) {
          } else {
            console.log('Data for timestamp ' + row.timestamp + ' is already logged.');
            return callback(null); // Not an error.
          }
        }
        return callback(err);
      });

    },

    put: function (putCallback) {
      var params = {
        TableName: locationsTable,
        Item: {
          timestamp: row.timestamp,
          locations: row.locations
        }
      };

      var saved = false;
      async.whilst( function() {
          return !saved;
        }, function (whilstCb) {
        docClient.put(params, function (err, data) {
          saved = true;
          if (err && err.retryable === true) {
            saved = false;
            return whilstCb(null);
          }
          return whilstCb(err);
        });
      }, function (err, data) {
        return putCallback(err);
      });
    },

    /**
     * Write to another table for sortability
     */
    grains: function (grainsCallback) {
      var params = {
        TableName: grainsTable,
        Item: {
          domain: 1,
          timestamp: row.timestamp,
          count: row.count
        }
      };

      var saved = false;
      async.whilst( function() {
          return !saved;
        }, function (whilstCb) {
        docClient.put(params, function (err, data) {
          saved = true;
          if (err && err.retryable === true) {
            saved = false;
            whilstCb(null);
          }
          whilstCb(err);
        });
      }, function (err, data) {
        return grainsCallback(err);
      });
    },
  }, function (err) {
    if (err) {
      return next(err);
    } else {
      console.log(row.count + ' (' + row.locations.length + ') locations saved successfully with timestamp ' + row.timestamp);
      return next(null);
    }
  });
}
<|endoftext|>