<commit_before>suite('Scheduler', function() {
  var _                 = require('lodash');
  var assert            = require('assert');
  var assume            = require('assume');
  var Scheduler         = require('../lib/scheduler');
  var debug             = require('debug')('test:test_schedule_hooks');
  var helper            = require('./helper');
  var taskcreator       = require('../lib/taskcreator');
  var taskcluster       = require('taskcluster-client');

  this.slow(500);
  helper.setup();

  var scheduler = null;
  var creator = null;
  setup(async () => {
    creator = new taskcreator.MockTaskCreator();
    let notify = require('./fake-notify');
    scheduler = new Scheduler({
      Hook: helper.Hook,
      taskcreator: creator,
      pollingDelay: 1,
      notify: notify,
    });
  });

  teardown(async () => {
    if (scheduler) {
      await scheduler.terminate();
    }
    scheduler = null;
  });

  test('calls its poll method in a loop when started', async () => {
    var callCount = 0;
    scheduler.poll = () => { callCount += 1; };
    scheduler.pollingDelay = 1;  // 1 ms

    // run for a while..
    scheduler.start();
    await new Promise((accept) => { setTimeout(accept, 5); });

    // verify it polled
    var newCallCount = callCount;
    assume(1).lessThan(newCallCount);
    assume(newCallCount).lessThan(7);

    // terminate and run for a while longer
    scheduler.terminate();
    await new Promise((accept) => { setTimeout(accept, 5); });

    // verify it didn't poll any more
    assume(callCount).equals(newCallCount);
  });

  suite('poll method', function() {
    setup(async () => {
      await scheduler.Hook.scan({}, {handler: hook => {return hook.remove();}});
      var hookParams = {
        hookGroupId:        'tests',
        metadata:           {},
        task:               {},
        bindings:           [],
        deadline:           '1 day',
        expires:            '1 day',
        schedule:           ['0 0 0 * * *'],
        lastFire:           {result: 'no-fire'},
        triggerToken:       taskcluster.slugid(),
      };

      await scheduler.Hook.create(_.defaults({
        hookId:             'futureHook',
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(4000, 0, 0, 0, 0, 0, 0),
      }, hookParams));

      await scheduler.Hook.create(_.defaults({
        hookId:             'pastHook',
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(2000, 0, 0, 0, 0, 0, 0),
      }, hookParams));

      await scheduler.Hook.create(_.defaults({
        hookId:             'pastHookNotScheduled',
        nextTaskId:         taskcluster.slugid(),
        schedule:           [],
        nextScheduledDate:  new Date(4000, 0, 0, 0, 0, 0, 0),
      }, hookParams));
    });

    test('calls handleHook only for past-due hooks', async () => {
      var handled = [];
      scheduler.handleHook = async (hook) => handled.push(hook.hookId);
      await scheduler.poll();
      assume(handled).eql(['pastHook']);
    });
  });

  suite('handleHook method', function() {
    var hook;

    setup(async () => {
      await scheduler.Hook.scan({}, {handler: hook => {return hook.remove();}});

      hook = await scheduler.Hook.create({
        hookGroupId:        'tests',
        hookId:             'test',
        metadata:           {
          owner: 'example@example.com',
        },
        task:               {
          provisionerId: 'no-provisioner',
          workerType: 'test-worker',
          metadata: {
            name: 'test task',
            description: 'task created by tc-hooks tests',
            owner: 'taskcluster@mozilla.com',
            source: 'http://taskcluster.net',
          },
          payload: {},
        },
        bindings:           [],
        deadline:           '1 day',
        expires:            '1 day',
        schedule:           ['0 0 0 * * *'],
        triggerToken:       taskcluster.slugid(),
        lastFire:           {result: 'no-fire'},
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(3000, 0, 0, 0, 0, 0, 0),
      });
    });

    test('creates a new task and updates nextTaskId, lastFire, nextScheduledDate', async () => {
      let oldTaskId = hook.nextTaskId;
      let oldScheduledDate = hook.nextScheduledDate;

      await scheduler.handleHook(hook);

      let updatedHook = await scheduler.Hook.load({
        hookGroupId: 'tests',
        hookId:      'test',
      }, true);

      assume(creator.fireCalls).deep.equals([{
        hookGroupId: 'tests',
        hookId: 'test',
        payload: {},
        options: {
          taskId: oldTaskId,
          created: new Date(3000, 0, 0, 0, 0, 0, 0),
          retry: false,
        },
      }]);
      assume(updatedHook.nextTaskId).is.not.equal(oldTaskId);
      assume(updatedHook.lastFire.result).is.equal('success');
      assume(updatedHook.lastFire.taskId).is.equal(oldTaskId);
      assume(new Date(updatedHook.lastFire.time) - new Date()).is.approximately(0, 2000); // 2s slop
      assume(updatedHook.nextScheduledDate).is.not.equal(oldScheduledDate);
    });

    test('on error, sends an email and updates nextTaskId, lastFire, nextScheduledDate', async () => {
      let oldTaskId = hook.nextTaskId;
      let oldScheduledDate = hook.nextScheduledDate;

      creator.shouldFail = true;

      let emailSent = false;
      scheduler.sendFailureEmail = async (hook, err) => { emailSent = true; };

      await scheduler.handleHook(hook);

      assume(emailSent).is.equal(true);

      let updatedHook = await scheduler.Hook.load({
        hookGroupId: 'tests',
        hookId:      'test',
      }, true);

      assume(updatedHook.nextTaskId).is.not.equal(oldTaskId);
      assume(updatedHook.lastFire.result).is.equal('error');
      assume(updatedHook.lastFire.error.statusCode).is.equal(499);
      assume(new Date(updatedHook.lastFire.time) - new Date()).is.approximately(0, 2000); // 2s slop
      assume(updatedHook.nextScheduledDate).is.not.equal(oldScheduledDate);
    });

    test('on error, notify is used with correct options', async () => {
      let oldTaskId = hook.nextTaskId;
      let oldScheduledDate = hook.nextScheduledDate;

      creator.shouldFail = true;

      await scheduler.handleHook(hook);
      assume(scheduler.notify.credentials).exists();
      assume(scheduler.notify.authorizedScopes).exists();
      assume(scheduler.notify.lastEmail).exists();

      let lastEmail = scheduler.notify.lastEmail;
      let email = scheduler.createEmail(hook, lastEmail.err, lastEmail.errJson);
      assume(lastEmail.address).is.equal(email.address);
      assume(lastEmail.subject).is.equal(email.subject);
      assume(lastEmail.content).is.equal(email.content);
    });
  });
});
<commit_msg>setting emailOnError to true<commit_after>suite('Scheduler', function() {
  var _                 = require('lodash');
  var assert            = require('assert');
  var assume            = require('assume');
  var Scheduler         = require('../lib/scheduler');
  var debug             = require('debug')('test:test_schedule_hooks');
  var helper            = require('./helper');
  var taskcreator       = require('../lib/taskcreator');
  var taskcluster       = require('taskcluster-client');

  this.slow(500);
  helper.setup();

  var scheduler = null;
  var creator = null;
  setup(async () => {
    creator = new taskcreator.MockTaskCreator();
    let notify = require('./fake-notify');
    scheduler = new Scheduler({
      Hook: helper.Hook,
      taskcreator: creator,
      pollingDelay: 1,
      notify: notify,
    });
  });

  teardown(async () => {
    if (scheduler) {
      await scheduler.terminate();
    }
    scheduler = null;
  });

  test('calls its poll method in a loop when started', async () => {
    var callCount = 0;
    scheduler.poll = () => { callCount += 1; };
    scheduler.pollingDelay = 1;  // 1 ms

    // run for a while..
    scheduler.start();
    await new Promise((accept) => { setTimeout(accept, 5); });

    // verify it polled
    var newCallCount = callCount;
    assume(1).lessThan(newCallCount);
    assume(newCallCount).lessThan(7);

    // terminate and run for a while longer
    scheduler.terminate();
    await new Promise((accept) => { setTimeout(accept, 5); });

    // verify it didn't poll any more
    assume(callCount).equals(newCallCount);
  });

  suite('poll method', function() {
    setup(async () => {
      await scheduler.Hook.scan({}, {handler: hook => {return hook.remove();}});
      var hookParams = {
        hookGroupId:        'tests',
        metadata:           {},
        task:               {},
        bindings:           [],
        deadline:           '1 day',
        expires:            '1 day',
        schedule:           ['0 0 0 * * *'],
        lastFire:           {result: 'no-fire'},
        triggerToken:       taskcluster.slugid(),
      };

      await scheduler.Hook.create(_.defaults({
        hookId:             'futureHook',
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(4000, 0, 0, 0, 0, 0, 0),
      }, hookParams));

      await scheduler.Hook.create(_.defaults({
        hookId:             'pastHook',
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(2000, 0, 0, 0, 0, 0, 0),
      }, hookParams));

      await scheduler.Hook.create(_.defaults({
        hookId:             'pastHookNotScheduled',
        nextTaskId:         taskcluster.slugid(),
        schedule:           [],
        nextScheduledDate:  new Date(4000, 0, 0, 0, 0, 0, 0),
      }, hookParams));
    });

    test('calls handleHook only for past-due hooks', async () => {
      var handled = [];
      scheduler.handleHook = async (hook) => handled.push(hook.hookId);
      await scheduler.poll();
      assume(handled).eql(['pastHook']);
    });
  });

  suite('handleHook method', function() {
    var hook;

    setup(async () => {
      await scheduler.Hook.scan({}, {handler: hook => {return hook.remove();}});

      hook = await scheduler.Hook.create({
        hookGroupId:        'tests',
        hookId:             'test',
        metadata:           {
          owner: 'example@example.com',
        },
        task:               {
          provisionerId: 'no-provisioner',
          workerType: 'test-worker',
          metadata: {
            name: 'test task',
            description: 'task created by tc-hooks tests',
            owner: 'taskcluster@mozilla.com',
            source: 'http://taskcluster.net',
          },
          payload: {},
        },
        bindings:           [],
        deadline:           '1 day',
        expires:            '1 day',
        schedule:           ['0 0 0 * * *'],
        triggerToken:       taskcluster.slugid(),
        lastFire:           {result: 'no-fire'},
        nextTaskId:         taskcluster.slugid(),
        nextScheduledDate:  new Date(3000, 0, 0, 0, 0, 0, 0),
      });
    });

    test('creates a new task and updates nextTaskId, lastFire, nextScheduledDate', async () => {
      let oldTaskId = hook.nextTaskId;
      let oldScheduledDate = hook.nextScheduledDate;

      await scheduler.handleHook(hook);

      let updatedHook = await scheduler.Hook.load({
        hookGroupId: 'tests',
        hookId:      'test',
      }, true);

      assume(creator.fireCalls).deep.equals([{
        hookGroupId: 'tests',
        hookId: 'test',
        payload: {},
        options: {
          taskId: oldTaskId,
          created: new Date(3000, 0, 0, 0, 0, 0, 0),
          retry: false,
        },
      }]);
      assume(updatedHook.nextTaskId).is.not.equal(oldTaskId);
      assume(updatedHook.lastFire.result).is.equal('success');
      assume(updatedHook.lastFire.taskId).is.equal(oldTaskId);
      assume(new Date(updatedHook.lastFire.time) - new Date()).is.approximately(0, 2000); // 2s slop
      assume(updatedHook.nextScheduledDate).is.not.equal(oldScheduledDate);
    });

    test('on error, sends an email and updates nextTaskId, lastFire, nextScheduledDate', async () => {
      let oldTaskId = hook.nextTaskId;
      let oldScheduledDate = hook.nextScheduledDate;

      creator.shouldFail = true;

      let emailSent = false;
      scheduler.sendFailureEmail = async (hook, err) => { emailSent = true; };

      await scheduler.handleHook(hook);

      assume(emailSent).is.equal(true);

      let updatedHook = await scheduler.Hook.load({
        hookGroupId: 'tests',
        hookId:      'test',
      }, true);

      assume(updatedHook.nextTaskId).is.not.equal(oldTaskId);
      assume(updatedHook.lastFire.result).is.equal('error');
      assume(updatedHook.lastFire.error.statusCode).is.equal(499);
      assume(new Date(updatedHook.lastFire.time) - new Date()).is.approximately(0, 2000); // 2s slop
      assume(updatedHook.nextScheduledDate).is.not.equal(oldScheduledDate);
    });

    test('on error, notify is used with correct options', async () => {
      creator.shouldFail = true;
      hook.metadata.emailOnError = true;
      await scheduler.handleHook(hook);

      assume(scheduler.notify.credentials).exists();
      assume(scheduler.notify.authorizedScopes).exists();
      assume(scheduler.notify.lastEmail).exists();

      let lastEmail = scheduler.notify.lastEmail;
      let email = scheduler.createEmail(hook, lastEmail.err, lastEmail.errJson);

      assume(lastEmail.address).is.equal(email.address);
      assume(lastEmail.subject).is.equal(email.subject);
      assume(lastEmail.content).is.equal(email.content);
    });
  });
});
<|endoftext|>


<commit_before>require('shelljs/make');
require('shelljs/global');

// Targets

target.all = function () {
  target.test();
  target.minify();
  target.boilerplate();
};

target.highlighter = function () {
  console.log('Bundling highlighter...');

  rm('-rf', 'vendor/highlight.js');
  mkdir('-p', 'vendor');
  pushd('vendor');
  exec('git clone https://github.com/isagalaev/highlight.js.git');
  pushd('highlight.js');
  exec('git checkout tags/8.0');
  popd();
  popd();

  bundleHighlighter('src/remark/highlighter.js');
};

target.test = function () {
  target['lint']();
  target['bundle']();
  target['test-bundle']();

  console.log('Running tests...');
  run('mocha-phantomjs test/runner.html');
};

target.lint = function () {
  console.log('Linting...');
  run('jshint src', {silent: true});
};

target.bundle = function () {
  console.log('Bundling...');
  bundleResources('src/remark/resources.js');

  mkdir('out');

  run('browserify ' + components() + ' src/remark.js',
      {silent: true}).output.to('out/remark.js');
};

function components () {
  var componentsPath = './src/remark/components';

  return ls(componentsPath)
    .map(function (component) {
      return '-r ' + componentsPath + '/' + component + '/' + component +
        '.js:' + 'components/' + component;
    })
    .join(' ');
}

target['test-bundle'] = function () {
  console.log('Bundling tests...');

  [
    "require('should');",
    "require('sinon');"
  ]
    .concat(find('./test')
      .filter(function(file) { return file.match(/\.js$/); })
      .map(function (file) { return "require('./" + file + "');" })
    )
      .join('\n')
      .to('_tests.js');

  run('browserify ' + components() + ' _tests.js',
      {silent: true}).output.to('out/tests.js');
  rm('_tests.js');
};

target.boilerplate = function () {
  console.log('Generating boilerplate...');
  generateBoilerplateSingle("boilerplate-single.html");
};

target.minify = function () {
  console.log('Minifying...');
  run('uglifyjs out/remark.js', {silent: true}).output.to('out/remark.min.js');
};

target.deploy = function () {
  var currentBranch = git('branch')
    .split('\n')
    .filter(function (line) {
      return line[0] === '*';
    })[0]
    .substr(2);

  var version = require('./package.json').version;
  var tagForVersion = git('tag -l v' + version);

  if (tagForVersion) {
    console.log('Update version in package.json before deploying.');
    return;
  }

  git('add package.json');
  git('add -f out');
  git('checkout head');
  git('commit -m "Deploy version ' + version + '."');
  git('tag -a v' + version + ' -m "Version ' + version + '."');
  git('checkout ' + currentBranch);
  git('push origin --tags');
};

// Helper functions

var path = require('path')
  , config = require('./package.json').config
  , ignoredStyles = ['brown_paper', 'school_book', 'pojoaque']
  ;

function bundleResources (target) {
  var resources = {
        DOCUMENT_STYLES: JSON.stringify(
          less('src/remark.less'))
      , CONTAINER_LAYOUT: JSON.stringify(
          cat('src/remark.html'))
      };

  cat('src/templates/resources.js.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function bundleHighlighter (target) {
  var highlightjs = 'vendor/highlight.js/src/'
    , resources = {
        HIGHLIGHTER_STYLES: JSON.stringify(
          ls(highlightjs + 'styles/*.css').reduce(mapStyle, {}))
      , HIGHLIGHTER_ENGINE:
          cat(highlightjs + 'highlight.js')
      , HIGHLIGHTER_LANGUAGES:
          config.highlighter.languages.map(function (language) {
            return '{name:"' + language + '",create:' +
              cat(highlightjs + 'languages/' + language + '.js') + '}';
          }).join(',')
      };

  cat('src/templates/highlighter.js.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function generateBoilerplateSingle(target) {
  var resources = {
        REMARK_MINJS: escape(cat('out/remark.min.js')
                              // highlighter has a ending script tag as a string literal, and
                              // that causes early termination of escaped script. Split that literal.
                              .replace('"</script>"', '"</" + "script>"'))
      };

  cat('src/templates/boilerplate-single.html.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function mapStyle (map, file) {
  var key = path.basename(file, path.extname(file))
    , tmpfile = path.join(tempdir(), 'remark.tmp')
    ;

  if (ignoredStyles.indexOf(key) === -1) {
    ('.hljs-' + key + ' {\n' + cat(file) + '\n}').to(tmpfile);
    map[key] = less(tmpfile);
    rm(tmpfile);
  }

  return map;
}

function less (file) {
  return run('lessc -x ' + file, {silent: true}).output.replace(/\n/g, '');
}

function git (cmd) {
  return exec('git ' + cmd, {silent: true}).output;
}

function run (command, options) {
  var result = exec(pwd() + '/node_modules/.bin/' + command, options);

  if (result.code !== 0) {
    if (!options || options.silent) {
      console.error(result.output);
    }
    exit(1);
  }

  return result;
}
<commit_msg>Handle existing out directory.<commit_after>require('shelljs/make');
require('shelljs/global');

// Targets

target.all = function () {
  target.test();
  target.minify();
  target.boilerplate();
};

target.highlighter = function () {
  console.log('Bundling highlighter...');

  rm('-rf', 'vendor/highlight.js');
  mkdir('-p', 'vendor');
  pushd('vendor');
  exec('git clone https://github.com/isagalaev/highlight.js.git');
  pushd('highlight.js');
  exec('git checkout tags/8.0');
  popd();
  popd();

  bundleHighlighter('src/remark/highlighter.js');
};

target.test = function () {
  target['lint']();
  target['bundle']();
  target['test-bundle']();

  console.log('Running tests...');
  run('mocha-phantomjs test/runner.html');
};

target.lint = function () {
  console.log('Linting...');
  run('jshint src', {silent: true});
};

target.bundle = function () {
  console.log('Bundling...');
  bundleResources('src/remark/resources.js');

  mkdir('-p', 'out');

  run('browserify ' + components() + ' src/remark.js',
      {silent: true}).output.to('out/remark.js');
};

function components () {
  var componentsPath = './src/remark/components';

  return ls(componentsPath)
    .map(function (component) {
      return '-r ' + componentsPath + '/' + component + '/' + component +
        '.js:' + 'components/' + component;
    })
    .join(' ');
}

target['test-bundle'] = function () {
  console.log('Bundling tests...');

  [
    "require('should');",
    "require('sinon');"
  ]
    .concat(find('./test')
      .filter(function(file) { return file.match(/\.js$/); })
      .map(function (file) { return "require('./" + file + "');" })
    )
      .join('\n')
      .to('_tests.js');

  run('browserify ' + components() + ' _tests.js',
      {silent: true}).output.to('out/tests.js');
  rm('_tests.js');
};

target.boilerplate = function () {
  console.log('Generating boilerplate...');
  generateBoilerplateSingle("boilerplate-single.html");
};

target.minify = function () {
  console.log('Minifying...');
  run('uglifyjs out/remark.js', {silent: true}).output.to('out/remark.min.js');
};

target.deploy = function () {
  var currentBranch = git('branch')
    .split('\n')
    .filter(function (line) {
      return line[0] === '*';
    })[0]
    .substr(2);

  var version = require('./package.json').version;
  var tagForVersion = git('tag -l v' + version);

  if (tagForVersion) {
    console.log('Update version in package.json before deploying.');
    return;
  }

  git('add package.json');
  git('add -f out');
  git('checkout head');
  git('commit -m "Deploy version ' + version + '."');
  git('tag -a v' + version + ' -m "Version ' + version + '."');
  git('checkout ' + currentBranch);
  git('push origin --tags');
};

// Helper functions

var path = require('path')
  , config = require('./package.json').config
  , ignoredStyles = ['brown_paper', 'school_book', 'pojoaque']
  ;

function bundleResources (target) {
  var resources = {
        DOCUMENT_STYLES: JSON.stringify(
          less('src/remark.less'))
      , CONTAINER_LAYOUT: JSON.stringify(
          cat('src/remark.html'))
      };

  cat('src/templates/resources.js.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function bundleHighlighter (target) {
  var highlightjs = 'vendor/highlight.js/src/'
    , resources = {
        HIGHLIGHTER_STYLES: JSON.stringify(
          ls(highlightjs + 'styles/*.css').reduce(mapStyle, {}))
      , HIGHLIGHTER_ENGINE:
          cat(highlightjs + 'highlight.js')
      , HIGHLIGHTER_LANGUAGES:
          config.highlighter.languages.map(function (language) {
            return '{name:"' + language + '",create:' +
              cat(highlightjs + 'languages/' + language + '.js') + '}';
          }).join(',')
      };

  cat('src/templates/highlighter.js.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function generateBoilerplateSingle(target) {
  var resources = {
        REMARK_MINJS: escape(cat('out/remark.min.js')
                              // highlighter has a ending script tag as a string literal, and
                              // that causes early termination of escaped script. Split that literal.
                              .replace('"</script>"', '"</" + "script>"'))
      };

  cat('src/templates/boilerplate-single.html.template')
    .replace(/%(\w+)%/g, function (match, key) {
      return resources[key];
    })
    .to(target);
}

function mapStyle (map, file) {
  var key = path.basename(file, path.extname(file))
    , tmpfile = path.join(tempdir(), 'remark.tmp')
    ;

  if (ignoredStyles.indexOf(key) === -1) {
    ('.hljs-' + key + ' {\n' + cat(file) + '\n}').to(tmpfile);
    map[key] = less(tmpfile);
    rm(tmpfile);
  }

  return map;
}

function less (file) {
  return run('lessc -x ' + file, {silent: true}).output.replace(/\n/g, '');
}

function git (cmd) {
  return exec('git ' + cmd, {silent: true}).output;
}

function run (command, options) {
  var result = exec(pwd() + '/node_modules/.bin/' + command, options);

  if (result.code !== 0) {
    if (!options || options.silent) {
      console.error(result.output);
    }
    exit(1);
  }

  return result;
}
<|endoftext|>


<commit_before>/* jshint mocha: true, expr: true, strict: false */

describe('test suite', function () {
  it('should assert true', function () {
    true.should.be.true;
    false.should.be.false;
  });
});

describe('hello', function () {
  it('should return world', function () {
    hello().should.equal('world');
  });
});

describe('getStock', function () {
  it('should return a stock object', function (done) {
    getStock('AAPL', function (stock){
      stock.Name.should.equal('Apple Inc');
      done();
    });
  });
  it('should return another stock object', function (done) {
    getStock('MSFT', function (stock) {
      stock.Name.should.equal('Microsoft Corp');
      done();
    });
  });
});

describe('addStockToTable', function () {
  it('should add a row to the table', function () {
    var stock = { Name: 'SuperCorp', Symbol: 'SCRP', LastPrice: 12.34 };
    $('tr').length.should.equal(0);
    addStockToTable(stock);
    $('tr').length.should.equal(1);
  });
  it('should use stock data in the appended row', function () {
    var stock = { Name: 'Super Corp', Symbol: 'SCRP', LastPrice: 12.34 },
        $row  = addStockToTable(stock),
        $tds  = $row.find('td');

    $tds.length.should.equal(4);
    $($tds[0]).text().should.equal('Super Corp');
    $($tds[1]).text().should.equal('SCRP');
    $($tds[2]).text().should.equal('12.34');
    $($tds[3]).text().should.equal('12.34');
  });
});

describe('getMultipleStocks', function () {
  it('should return multiple stock objects', function (done) {
    getMultipleStocks(['AAPL', 'MSFT'], function (stocks) {
      stocks.length.should.equal(2);
      stocks[0].Name.should.equal('Apple Inc');
      stocks[1].Name.should.equal('Microsoft Corp');
      done();
    });
  });
});

describe('refreshStockPrices', function () {
  it('should edit each stock in the table with the new price', function () {
    var stocks = [
      { Symbol: 'AAPL' , LastPrice: 12.45 },
      { Symbol: 'MSFT' , LastPrice: 23.56 }
    ],
        $tbody = $('tbody'),
        $trs   = $('tr');

    $tbody.append('
Apple Inc	AAPL	12.34	12.34
');
    $tbody.append('
Microsoft Corp	MSFT	23.45	23.45
');

    refreshStockPrices(stocks);

    $($($trs[0]).find('td')[3]).text().should.equal('12.45');
    $($($trs[1]).find('td')[3]).text().should.equal('23.56');
  });
});
<commit_msg>reorganization of tests<commit_after>/* jshint mocha: true, expr: true, strict: false */

describe('test suite', function () {
  it('should assert true', function () {
    true.should.be.true;
    false.should.be.false;
  });
});

describe('hello', function () {
  it('should return world', function () {
    hello().should.equal('world');
  });
});

describe('DOM', function() {
  describe('table', function() {
    beforeEach(function() {
      $('tbody').empty();
    });

    describe('addStockToTable', function () {
      it('should add a row to the table', function () {
        var stock = { Name: 'SuperCorp', Symbol: 'SCRP', LastPrice: 12.34 };
        $('tr').length.should.equal(0);
        addStockToTable(stock);
        $('tr').length.should.equal(1);
      });
      it('should use stock data in the appended row', function () {
        var stock = { Name: 'Super Corp', Symbol: 'SCRP', LastPrice: 12.34 },
            $row  = addStockToTable(stock),
            $tds  = $row.find('td');

        $tds.length.should.equal(4);
        $($tds[0]).text().should.equal('Super Corp');
        $($tds[1]).text().should.equal('SCRP');
        $($tds[2]).text().should.equal('12.34');
        $($tds[3]).text().should.equal('12.34');
      });
    });

    describe('refreshStockPrices', function () {
      it('should edit each stock in the table with the new price', function () {
        var stocks = [
          { Symbol: 'AAPL' , LastPrice: 12.45 },
          { Symbol: 'MSFT' , LastPrice: 23.56 }
        ],
            $tbody = $('tbody'),
            $trs;

        $tbody.append('
Apple Inc	AAPL	12.34	12.34
');
        $tbody.append('
Microsoft Corp	MSFT	23.45	23.45
');
        $trs   = $('tr');

        refreshStockPrices(stocks);

        $($($trs[0]).find('td')[3]).text().should.equal('12.45');
        $($($trs[1]).find('td')[3]).text().should.equal('23.56');
      });
    });
  });
});

describe('ASYNC', function() {
  describe('getStock', function () {
    it('should return a stock object', function (done) {
      getStock('AAPL', function (stock){
        stock.Name.should.equal('Apple Inc');
        done();
      });
    });
    it('should return another stock object', function (done) {
      getStock('MSFT', function (stock) {
        stock.Name.should.equal('Microsoft Corp');
        done();
      });
    });
  });

  describe('getMultipleStocks', function () {
    it('should return multiple stock objects', function (done) {
      getMultipleStocks(['AAPL', 'MSFT'], function (stocks) {
        stocks.length.should.equal(2);
        stocks[0].Name.should.equal('Apple Inc');
        stocks[1].Name.should.equal('Microsoft Corp');
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>require('shelljs/make');
require('shelljs/global');

var fs      = require('fs')
  , path = require('path')
  , browserify = require('browserify')
  , UglifyJS = require("uglify-js")
  , less = require('less')
  ;

var buildPath = path.join(__dirname, 'build/socialfeed.js')
  , minifiedPath = path.join(__dirname, 'build/socialfeed.min.js');

target.all = function () {
  target.bundle(function () {
    target.less(function () {
      target.minify();
    });
  });
};

target.bundle = function (cb) {
  console.log('Bundle');
  bundleResources('src/moduletemplates/', 'src/resources.js');
  bundle(cb);
};

target.less = function (cb) {
  console.log('Compiling LESS');
  var data = fs.readFileSync('src/style.less');
  data = data.toString();

  var parser = new(less.Parser)({
    paths: ['./src'], // Specify search paths for @import directives
    filename: 'style.less' // Specify a filename, for better error messages
  });

  parser.parse(data, function (e, tree) {
    var css = tree.toCSS()
      , minified = tree.toCSS({ compress: true });
    fs.writeFile('build/socialfeed.css', css);
    console.log('Minifing CSS');
    fs.writeFile('build/socialfeed.min.css', minified, cb);
  });
};

target.minify = function () {
  console.log('Minifying...');
  var result = UglifyJS.minify(buildPath);
  fs.writeFileSync(minifiedPath, result.code);
  console.log('Minfying succeeded.');
};

function getResourcesList (templateFolder) {
  var filenames = fs.readdirSync(path.join(__dirname, templateFolder));
  return filenames.map(function (file) {
    return file.replace('.html', '');
  });
}

function bundleResources (source, target) {
  var templates = getResourcesList(source);

  var resourceString = "";
  templates.forEach(function (template) {
    resourceString += '\t"'+template+'": ' + JSON.stringify(cat(source + template + '.html')) + ",\n";
  });

  cat('src/resources.js.template').replace(/%BODY%/g, resourceString).to(path.join(__dirname, target));
}

function bundle(cb) {
  cb = cb || function () {};
  // This is function is the important part and should be similar to what you would use for your project
  browserify()
  .require(require.resolve('./src/socialfeed.js'), { entry: true })
  .bundle(function (err, src) {
    if (err) return console.error(err);

    fs.writeFileSync(buildPath, src);
    console.log('Build succeeded, open index.html to see the result.');
    cb();
  });
}

<commit_msg>Clean-up in make script<commit_after>require('shelljs/make');
require('shelljs/global');

var fs      = require('fs')
  , path = require('path')
  , browserify = require('browserify')
  , UglifyJS = require("uglify-js")
  , less = require('less')
  ;

var buildPath = path.join(__dirname, 'build/socialfeed.js')
  , minifiedPath = path.join(__dirname, 'build/socialfeed.min.js');

target.all = function () {
  target.bundle(function () {
    target.less(function () {
      target.minify();
    });
  });
};

target.bundle = function (cb) {
  console.log('Bundle');
  bundleResources('src/moduletemplates/', 'src/resources.js');
  bundle(cb);
};

target.less = function (cb) {
  console.log('Compiling LESS');
  var data = cat('src/style.less');

  var parser = new(less.Parser)({
      paths: ['./src']
    , filename: 'style.less'
  });

  parser.parse(data, function (e, tree) {
    var css = tree.toCSS()
      , minified = tree.toCSS({ compress: true });
    css.to('build/socialfeed.css');
    console.log('Minifing CSS');
    minified.to('build/socialfeed.min.css');
  });
};

target.minify = function () {
  console.log('Minifying...');
  UglifyJS.minify(buildPath).code.to(minifiedPath)
  console.log('Minfying succeeded.');
};

function getResourcesList (templateFolder) {
  var filenames = fs.readdirSync(path.join(__dirname, templateFolder));
  return filenames.map(function (file) {
    return file.replace('.html', '');
  });
}

function bundleResources (source, target) {
  var templates = getResourcesList(source);

  var resourceString = "";
  templates.forEach(function (template) {
    resourceString += '\t"'+template+'": ' + JSON.stringify(cat(source + template + '.html')) + ",\n";
  });

  cat('src/resources.js.template').replace(/%BODY%/g, resourceString).to(path.join(__dirname, target));
}

function bundle(cb) {
  cb = cb || function () {};

  browserify()
  .require(require.resolve('./src/socialfeed.js'), { entry: true })
  .bundle(function (err, src) {
    if (err) return console.error(err);

    src.to(buildPath);
    console.log('Build succeeded, open index.html to see the result.');
    cb();
  });
}

<|endoftext|>


<commit_before>const assert = require('assert');

const fs = require('fs');

const mailmake = require('../../lib/mailmake');

describe('mailmake', () => {
    before(() => {
        mailmake.seed = 's';
    });

    it('should generate random string', () => {
        assert.equal(mailmake.randomString(), 'ssssssssssssssssssss');
    });

    it('should generate boundary', () => {
        assert.equal(
            mailmake.boundaryString(),
            '==============ssssssssssssssssssss=='
        );
    });

    it('should generate mime file from file', done => {
        mailmake
            .generate('./test/fixtures/email.html', {
                from: 'test@example.com',
                subject: 'Hello World!',
                to: 'mailing-list@example.com'
            })
            .then(output => {
                // fs.writeFileSync('./test/fixtures/email.mime', output, 'utf8');

                fs.readFile(
                    './test/fixtures/email.mime',
                    'utf8',
                    (err, data) => {
                        assert.equal(output, data);

                        done();
                    }
                );
            });
    });

    it('should generate mime file from string', done => {
        fs.readFile('./test/fixtures/email.html', 'utf8', (err, email) => {
            mailmake
                .generate(email, {
                    from: 'test@example.com',
                    subject: 'Hello World!',
                    to: 'mailing-list@example.com'
                })
                .then(output => {
                    fs.readFile(
                        './test/fixtures/email.mime',
                        'utf8',
                        (err, data) => {
                            assert.equal(output, data);

                            done();
                        }
                    );
                });
        });
    });

    it('should generate mime file from string (private method)', done => {
        fs.readFile('./test/fixtures/email.html', 'utf8', (err, email) => {
            fs.readFile('./test/fixtures/email.mime', 'utf8', (err, data) => {
                assert.equal(
                    mailmake.generateFromString(email, {
                        from: 'test@example.com',
                        subject: 'Hello World!',
                        to: 'mailing-list@example.com'
                    }),
                    data
                );

                done();
            });
        });
    });
});
<commit_msg>Replaced deprecated method.<commit_after>const assert = require('assert');

const fs = require('fs');

const mailmake = require('../../lib/mailmake');

describe('mailmake', () => {
    before(() => {
        mailmake.seed = 's';
    });

    it('should generate random string', () => {
        assert.strictEqual(mailmake.randomString(), 'ssssssssssssssssssss');
    });

    it('should generate boundary', () => {
        assert.strictEqual(
            mailmake.boundaryString(),
            '==============ssssssssssssssssssss=='
        );
    });

    it('should generate mime file from file', done => {
        mailmake
            .generate('./test/fixtures/email.html', {
                from: 'test@example.com',
                subject: 'Hello World!',
                to: 'mailing-list@example.com'
            })
            .then(output => {
                // fs.writeFileSync('./test/fixtures/email.mime', output, 'utf8');

                fs.readFile(
                    './test/fixtures/email.mime',
                    'utf8',
                    (err, data) => {
                        assert.strictEqual(output, data);

                        done();
                    }
                );
            });
    });

    it('should generate mime file from string', done => {
        fs.readFile('./test/fixtures/email.html', 'utf8', (err, email) => {
            mailmake
                .generate(email, {
                    from: 'test@example.com',
                    subject: 'Hello World!',
                    to: 'mailing-list@example.com'
                })
                .then(output => {
                    fs.readFile(
                        './test/fixtures/email.mime',
                        'utf8',
                        (err, data) => {
                            assert.strictEqual(output, data);

                            done();
                        }
                    );
                });
        });
    });

    it('should generate mime file from string (private method)', done => {
        fs.readFile('./test/fixtures/email.html', 'utf8', (err, email) => {
            fs.readFile('./test/fixtures/email.mime', 'utf8', (err, data) => {
                assert.strictEqual(
                    mailmake.generateFromString(email, {
                        from: 'test@example.com',
                        subject: 'Hello World!',
                        to: 'mailing-list@example.com'
                    }),
                    data
                );

                done();
            });
        });
    });
});
<|endoftext|>


<commit_before>define([
	"intern!object",
	"intern/chai!assert",
	"../handlebars",
	"dui/register",
	"dui/Widget",
	"dui/handlebars!templates/SimpleHandleBarsButton.html",
	"dui/handlebars!templates/HandlebarsButton.html"
], function (registerSuite, assert, handlebars, register, Widget, simpleHBTmpl, buttonHBTmpl) {
	var container, myButton;
	registerSuite({
		name: "handlebars",
		setup: function () {
			container = document.createElement("div");
			document.body.appendChild(container);
		},
		"load" : function () {
			// Test that function returned from dui/handlebars! creates the template correctly
			var TestButton = register("test-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				label: "original label",
				buildRendering: simpleHBTmpl
			});
			myButton = new TestButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("original label", myButton.textContent.trim(), "label set");
		},
		"update" : function () {
			myButton.label = "new label";
			assert.deepEqual("new label", myButton.textContent.trim(), "label updated");

			myButton.iconClass = "newClass";
			assert.deepEqual("duiReset newClass", myButton.firstChild.className, "icon class set");

		},
		"branching" : function () {
			var NoLabelButton = register("no-label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: false,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new NoLabelButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("", myButton.textContent.trim(), "no label");
			myButton.label = "new label";
			assert.deepEqual("", myButton.textContent.trim(), "still no label");

			// Test true if condition
			var LabelButton = register("label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: true,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new LabelButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("original label", myButton.textContent.trim(), "label");

			// Make sure that changes still work
			myButton.label = "new label";
			assert.deepEqual("new label", myButton.textContent.trim(), "label updated");

		},
		"Special props" : function () {
			var SpecialPropsWidget = register("special-props", [HTMLElement, Widget], {
				inputClass: "originalClass",	// attribute called "class" but property called "className"
				inputValue: "original value",	// must be set as property
				role: "originalRole",			// must be set as attribute
				buildRendering: handlebars.compile(
					'<special-props><input class="{{inputClass}}" value="{{inputValue}}" role="{{role}}"/></special-props>'
				)
			});
			var mySpecialPropsWidget = new SpecialPropsWidget();
			var input = mySpecialPropsWidget.children[0];

			assert.deepEqual("original value", input.value, "value set as property");
			assert.deepEqual("originalClass", input.className, "class set even though property is called className, not class");
			assert.deepEqual("originalRole", input.getAttribute("role"), "role set as attribute");

			mySpecialPropsWidget.mix({
				inputClass: "newClass",
				inputValue: "new value",
				role: "newRole"
			});
			assert.deepEqual("new value", input.value, "value changed");
			assert.deepEqual("newClass", input.className, "class changed");
			assert.deepEqual("newRole", input.getAttribute("role"), "role changed");

			// TODO: implement and then test reverse binding, from input.value --> widget.value?
		},
		"Widgets in Template" : function () {
			register("simple-heading", [HTMLElement, Widget], {
				text: "",
				buildRendering: handlebars.compile("<simple-heading>{{text}}</simple-heading>")
			});

			// This widget uses sub-widgets test-button (defined in first test) and also simple-heading.
			var ComplexWidget = register("widgets-in-template", [HTMLElement, Widget], {
				heading: "original heading",
				content: "original content",
				buttonLabel: "original button label",
				buildRendering: handlebars.compile(
					'<widgets-in-template>' +
						'<simple-heading text="{{heading}}"></simple-heading>' +
						'{{content}}' +
						'<button is="test-button" label="{{buttonLabel}}"></button>' +
						'</widgets-in-template>'
				)
			});

			var myComplexWidget = new ComplexWidget(),
				headingWidget = myComplexWidget.getElementsByTagName("simple-heading")[0],
				buttonWidget = myComplexWidget.getElementsByTagName("button")[0];
			assert.ok(headingWidget.buildRendering, "heading widget was instantiated");
			assert.deepEqual("original heading", headingWidget.textContent, "heading widget got title from main widget");
			assert.ok(buttonWidget.buildRendering, "button widget was instantiated");
			assert.deepEqual("original button label", buttonWidget.textContent.trim(), "button widget got label from main widget");

			myComplexWidget.mix({
				heading: "new heading",
				buttonLabel: "new button label"
			});
			assert.deepEqual("new heading", headingWidget.textContent, "heading changed");
			assert.deepEqual("new button label", buttonWidget.textContent.trim(), "button changed");

		},

		teardown : function () {
			container.parentNode = null;
		}
	});
});
<commit_msg>client.js tests broken after directory re-org, refs #54<commit_after>define([
	"intern!object",
	"intern/chai!assert",
	"../handlebars",
	"dui/register",
	"dui/Widget",
	"dui/handlebars!./templates/SimpleHandleBarsButton.html",
	"dui/handlebars!./templates/HandlebarsButton.html"
], function (registerSuite, assert, handlebars, register, Widget, simpleHBTmpl, buttonHBTmpl) {
	var container, myButton;
	registerSuite({
		name: "handlebars",
		setup: function () {
			container = document.createElement("div");
			document.body.appendChild(container);
		},
		"load" : function () {
			// Test that function returned from dui/handlebars! creates the template correctly
			var TestButton = register("test-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				label: "original label",
				buildRendering: simpleHBTmpl
			});
			myButton = new TestButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("original label", myButton.textContent.trim(), "label set");
		},
		"update" : function () {
			myButton.label = "new label";
			assert.deepEqual("new label", myButton.textContent.trim(), "label updated");

			myButton.iconClass = "newClass";
			assert.deepEqual("duiReset newClass", myButton.firstChild.className, "icon class set");

		},
		"branching" : function () {
			var NoLabelButton = register("no-label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: false,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new NoLabelButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("", myButton.textContent.trim(), "no label");
			myButton.label = "new label";
			assert.deepEqual("", myButton.textContent.trim(), "still no label");

			// Test true if condition
			var LabelButton = register("label-button", [HTMLButtonElement, Widget], {
				iconClass: "originalClass",
				showLabel: true,
				label: "original label",
				buildRendering: buttonHBTmpl
			});
			myButton = new LabelButton();
			assert.deepEqual("button", myButton.tagName.toLowerCase(), "root node exists");
			assert.deepEqual("span", myButton.firstChild.tagName.toLowerCase(), "icon node exists too");
			assert.deepEqual("duiReset originalClass", myButton.firstChild.className, "icon class set");
			assert.deepEqual("original label", myButton.textContent.trim(), "label");

			// Make sure that changes still work
			myButton.label = "new label";
			assert.deepEqual("new label", myButton.textContent.trim(), "label updated");

		},
		"Special props" : function () {
			var SpecialPropsWidget = register("special-props", [HTMLElement, Widget], {
				inputClass: "originalClass",	// attribute called "class" but property called "className"
				inputValue: "original value",	// must be set as property
				role: "originalRole",			// must be set as attribute
				buildRendering: handlebars.compile(
					'<special-props><input class="{{inputClass}}" value="{{inputValue}}" role="{{role}}"/></special-props>'
				)
			});
			var mySpecialPropsWidget = new SpecialPropsWidget();
			var input = mySpecialPropsWidget.children[0];

			assert.deepEqual("original value", input.value, "value set as property");
			assert.deepEqual("originalClass", input.className, "class set even though property is called className, not class");
			assert.deepEqual("originalRole", input.getAttribute("role"), "role set as attribute");

			mySpecialPropsWidget.mix({
				inputClass: "newClass",
				inputValue: "new value",
				role: "newRole"
			});
			assert.deepEqual("new value", input.value, "value changed");
			assert.deepEqual("newClass", input.className, "class changed");
			assert.deepEqual("newRole", input.getAttribute("role"), "role changed");

			// TODO: implement and then test reverse binding, from input.value --> widget.value?
		},
		"Widgets in Template" : function () {
			register("simple-heading", [HTMLElement, Widget], {
				text: "",
				buildRendering: handlebars.compile("<simple-heading>{{text}}</simple-heading>")
			});

			// This widget uses sub-widgets test-button (defined in first test) and also simple-heading.
			var ComplexWidget = register("widgets-in-template", [HTMLElement, Widget], {
				heading: "original heading",
				content: "original content",
				buttonLabel: "original button label",
				buildRendering: handlebars.compile(
					'<widgets-in-template>' +
						'<simple-heading text="{{heading}}"></simple-heading>' +
						'{{content}}' +
						'<button is="test-button" label="{{buttonLabel}}"></button>' +
						'</widgets-in-template>'
				)
			});

			var myComplexWidget = new ComplexWidget(),
				headingWidget = myComplexWidget.getElementsByTagName("simple-heading")[0],
				buttonWidget = myComplexWidget.getElementsByTagName("button")[0];
			assert.ok(headingWidget.buildRendering, "heading widget was instantiated");
			assert.deepEqual("original heading", headingWidget.textContent, "heading widget got title from main widget");
			assert.ok(buttonWidget.buildRendering, "button widget was instantiated");
			assert.deepEqual("original button label", buttonWidget.textContent.trim(), "button widget got label from main widget");

			myComplexWidget.mix({
				heading: "new heading",
				buttonLabel: "new button label"
			});
			assert.deepEqual("new heading", headingWidget.textContent, "heading changed");
			assert.deepEqual("new button label", buttonWidget.textContent.trim(), "button changed");

		},

		teardown : function () {
			container.parentNode = null;
		}
	});
});
<|endoftext|>


<commit_before>/**!
 * make.js, script to build the website for MPC-HC
 * Released under the terms of MIT license
 *
 * https://github.com/mpc-hc/website
 *
 * Copyright (C) 2013 MPC-HC Team
 */

/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true,
   camelcase:true, trailing:true, strict:true, boss:true, unused:true,
   curly:true, indent:4, maxerr:100 */
/*global cd, cp, target, echo, cat, exec, pushd, popd, rm, require, __dirname */

(function () {
    'use strict';

    require('shelljs/make');
    var fs = require('fs');
    var cleanCSS = require('clean-css');
    var UglifyJS = require('uglify-js');

    var ROOT_DIR = __dirname + '/',         // absolute path to project's root
        BUILD_DIR = ROOT_DIR + 'build/',
        BUILD_TARGET = BUILD_DIR + 'website/',
        SRC_DIR = ROOT_DIR + 'source/',
        SPHINXOPTS = '-d' + ' ' + BUILD_DIR + '/doctrees' + ' ' + SRC_DIR + ' ' + BUILD_TARGET;

    //
    // make all
    //
    target.all = function () {
        target.website();
    };

    //
    // make website
    //
    target.website = function () {
        cd(ROOT_DIR);
        echo();
        echo("### Building posts...");
        exec('python -u sphinxblog/gen.py');

        echo();
        echo("### Building site...");
        exec('sphinx-build -b dirhtml' + ' ' + SPHINXOPTS);

        echo();
        echo("### Removing files we don't need...");

        pushd(BUILD_TARGET);

        var filesToRemoveFromDist = [
            '.buildinfo',
            '_static/*.css',
            '_static/*.gif',
            '_static/*.js',
            '_static/*.png',
            '_static/css/*.css',
            '_static/favicon.ico',
            '_static/js/*.js',
            'genindex',
            'objects.inv',
            'search',
            'searchindex.js'];

        rm('-rf', filesToRemoveFromDist);

        popd();

        echo();
        echo("### Copying files...");

        pushd(SRC_DIR);

        cp('-f', '.htaccess', BUILD_TARGET);
        cp('-f', '_static/apple-touch-icon*.png', BUILD_TARGET);
        cp('-f', '_static/favicon.ico', BUILD_TARGET);
        cp('-f', '_static/js/jquery-*.min.js', BUILD_TARGET + '_static/js');
        cp('-f', 'robots.txt', BUILD_TARGET);
        cp('-f', 'version.txt', BUILD_TARGET);

        echo();
        echo("### Combining css files...");

        var inCss = cat(['_static/css/bootstrap.css',
                         '_static/css/bootstrap-responsive.css',
                         '_static/css/jquery.fancybox.css',
                         '_static/css/jquery.fancybox-thumbs.css',
                         '_static/css/style.css']);

        var outCss = BUILD_TARGET + '_static/css/pack.css';
        var minifiedCss = cleanCSS.process(inCss, {
                            removeEmpty: true,
                            keepSpecialComments: 0});

        fs.writeFileSync(outCss, minifiedCss, 'utf8');

        //exec('cleancss -o' + ' ' + outCss + ' ' + inCss + ' ' + '--s0');

        echo();
        echo("### Combining js files...");

        var inJs = ['_static/js/plugins.js',
                    '_static/js/bootstrap.js',
                    '_static/js/jquery-migrate.js',
                    '_static/js/jquery.mousewheel.js',
                    '_static/js/jquery.fancybox.js',
                    '_static/js/jquery.fancybox-thumbs.js'];

        var outJs = BUILD_TARGET + '_static/js/pack.js';
        var minifiedJs = UglifyJS.minify(inJs, {
                            warnings: false,
                            mangle: true});

        fs.writeFileSync(outJs, minifiedJs.code, 'utf8');
        //exec('uglifyjs' + ' ' + inJs.join(' ') + ' -o' + ' ' + outJs + --compress --mangle');

        echo();
        echo('### Build finished. The HTML pages are in' + ' ' + BUILD_TARGET + '.');

        popd();
    };

    //
    // make clean
    //
    target.clean = function () {
        cd(ROOT_DIR);
        echo();
        echo('### Cleaning build...');
        rm('-rf', BUILD_DIR);
    };

    //
    // make rebuild
    //
    target.rebuild = function () {
        target.clean();
        target.website();
    };

    //
    // make server
    //
    target.server = function () {
        cd(ROOT_DIR);
        echo();
        echo('### Starting webserver...');
        cd(BUILD_TARGET);
        exec('python -u -m SimpleHTTPServer', {async: true});
    };

    //
    // make help
    //
    target.help = function () {
        echo("Available targets:");
        echo("  website  builds the website");
        echo("  server   starts the webserver");
        echo("  clean    cleans the built website");
        echo("  rebuild  rebuilds the website");
        echo("  help     shows this help message");
    };

}());
<commit_msg>make.js: use an array for the files to copy to the dist dir<commit_after>/**!
 * make.js, script to build the website for MPC-HC
 * Released under the terms of MIT license
 *
 * https://github.com/mpc-hc/website
 *
 * Copyright (C) 2013 MPC-HC Team
 */

/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true,
   camelcase:true, trailing:true, strict:true, boss:true, unused:true,
   curly:true, indent:4, maxerr:100 */
/*global cd, cp, target, echo, cat, exec, pushd, popd, rm, require, __dirname */

(function () {
    'use strict';

    require('shelljs/make');
    var fs = require('fs');
    var cleanCSS = require('clean-css');
    var UglifyJS = require('uglify-js');

    var ROOT_DIR = __dirname + '/',         // absolute path to project's root
        BUILD_DIR = ROOT_DIR + 'build/',
        BUILD_TARGET = BUILD_DIR + 'website/',
        SRC_DIR = ROOT_DIR + 'source/',
        SPHINXOPTS = '-d' + ' ' + BUILD_DIR + '/doctrees' + ' ' + SRC_DIR + ' ' + BUILD_TARGET;

    //
    // make all
    //
    target.all = function () {
        target.website();
    };

    //
    // make website
    //
    target.website = function () {
        cd(ROOT_DIR);
        echo();
        echo("### Building posts...");
        exec('python -u sphinxblog/gen.py');

        echo();
        echo("### Building site...");
        exec('sphinx-build -b dirhtml' + ' ' + SPHINXOPTS);

        echo();
        echo("### Removing files we don't need...");

        pushd(BUILD_TARGET);

        var filesToRemoveFromDist = [
            '.buildinfo',
            '_static/*.css',
            '_static/*.gif',
            '_static/*.js',
            '_static/*.png',
            '_static/css/*.css',
            '_static/favicon.ico',
            '_static/js/*.js',
            'genindex',
            'objects.inv',
            'search',
            'searchindex.js'];

        rm('-rf', filesToRemoveFromDist);

        popd();

        echo();
        echo("### Copying files...");

        pushd(SRC_DIR);

        var filesToCopyToDist = [
            '.htaccess',
            'robots.txt',
            'version.txt',
            '_static/apple-touch-icon*.png',
            '_static/favicon.ico'];

        cp('-f', filesToCopyToDist, BUILD_TARGET);
        cp('-f', '_static/js/jquery-*.min.js', BUILD_TARGET + '_static/js');

        echo();
        echo("### Combining css files...");

        var inCss = cat(['_static/css/bootstrap.css',
                         '_static/css/bootstrap-responsive.css',
                         '_static/css/jquery.fancybox.css',
                         '_static/css/jquery.fancybox-thumbs.css',
                         '_static/css/style.css']);

        var outCss = BUILD_TARGET + '_static/css/pack.css';
        var minifiedCss = cleanCSS.process(inCss, {
                            removeEmpty: true,
                            keepSpecialComments: 0});

        fs.writeFileSync(outCss, minifiedCss, 'utf8');

        //exec('cleancss -o' + ' ' + outCss + ' ' + inCss + ' ' + '--s0');

        echo();
        echo("### Combining js files...");

        var inJs = ['_static/js/plugins.js',
                    '_static/js/bootstrap.js',
                    '_static/js/jquery-migrate.js',
                    '_static/js/jquery.mousewheel.js',
                    '_static/js/jquery.fancybox.js',
                    '_static/js/jquery.fancybox-thumbs.js'];

        var outJs = BUILD_TARGET + '_static/js/pack.js';
        var minifiedJs = UglifyJS.minify(inJs, {
                            warnings: false,
                            mangle: true});

        fs.writeFileSync(outJs, minifiedJs.code, 'utf8');
        //exec('uglifyjs' + ' ' + inJs.join(' ') + ' -o' + ' ' + outJs + --compress --mangle');

        echo();
        echo('### Build finished. The HTML pages are in' + ' ' + BUILD_TARGET + '.');

        popd();
    };

    //
    // make clean
    //
    target.clean = function () {
        cd(ROOT_DIR);
        echo();
        echo('### Cleaning build...');
        rm('-rf', BUILD_DIR);
    };

    //
    // make rebuild
    //
    target.rebuild = function () {
        target.clean();
        target.website();
    };

    //
    // make server
    //
    target.server = function () {
        cd(ROOT_DIR);
        echo();
        echo('### Starting webserver...');
        cd(BUILD_TARGET);
        exec('python -u -m SimpleHTTPServer', {async: true});
    };

    //
    // make help
    //
    target.help = function () {
        echo("Available targets:");
        echo("  website  builds the website");
        echo("  server   starts the webserver");
        echo("  clean    cleans the built website");
        echo("  rebuild  rebuilds the website");
        echo("  help     shows this help message");
    };

}());
<|endoftext|>


<commit_before>import GLMesh from "../gl/GLMesh.js";
import GLProgram from "../gl/GLProgram.js";
import GLTexture from "../gl/GLTexture.js";

let style = document.createElement("style");
style.textContent = `
  dlib-webglimage {
    display: block;
    position: relative;
  }
`;
document.head.appendChild(style);

export default class WebGLImageElement extends HTMLElement {
  constructor({
    tagName = "img"
  } = {}) {
    super();

    this._resizeBinded = this.resize.bind(this);

    this._data = document.createElement(tagName);
    this._canvas = document.createElement("canvas");
    this._canvas.style.width = "100%";
    this._canvas.style.height = "100%";
    this.appendChild(this._canvas);
    this.gl = this._canvas.getContext(WebGL2RenderingContext ? "webgl2" : "webgl", {
      premultipliedAlpha: false
    });

    this._mesh = new GLMesh({
      gl: this.gl,
      attributes: [
        ["position", {
          data: new Float32Array([
            -1, -1,
            -1, 1,
            1, -1,
            1, 1
          ]),
          size: 2
        }],
        ["uv", {
          data: new Float32Array([
            0, 1,
            0, 0,
            1, 1,
            1, 0
          ]),
          size: 2
        }]
      ]
    });

    this._texture = new GLTexture({
      gl: this.gl
    });
    this._texture.minFilter = this.gl.LINEAR;
    this._texture.wrapS = this._texture.wrapT = this.gl.CLAMP_TO_EDGE;

    this.program = new GLProgram({
      gl: this.gl,
      uniforms: [
        ["data", 0]
      ],
      vertexShader: `#version 300 es
        in vec2 position;
        in vec2 uv;

        out vec2 vUv;

        void main() {
          gl_Position = vec4(position, 0., 1.);
          vUv = uv;
        }
      `,
      fragmentShader: `#version 300 es
        precision highp float;

        uniform sampler2D data;

        in vec2 vUv;

        out vec4 fragColor;

        void main() {
          fragColor = texture(data, vUv);
          fragColor.rgb *= fragColor.a;
        }
      `
    });
    this.program.use();

    this.program.attributes.set(this._mesh.attributes);

    if(this.hasAttribute("src")) {
      this.src = this.getAttribute("src");
    }
  }

  connectedCallback() {
    window.addEventListener("resize", this._resizeBinded);
  }

  disconnectedCallback() {
    this.gl.getExtension("WEBGL_lose_context").loseContext();
    window.removeEventListener("resize", this._resizeBinded);
  }

  update() {
    this._texture.data = this._data;
    this.draw();
  }

  draw({
    width = this._canvas.width,
    height = this._canvas.height,
  } = {}) {
    this.gl.viewport(0, 0, width, height);
    this.gl.clearColor(0, 0, 0, 1);
    this.gl.clear(this.gl.COLOR_BUFFER_BIT);
    this._mesh.draw({
      mode: this.gl.TRIANGLE_STRIP,
      count: 4
    });
  }

  resize() {
    this._canvas.width = this.offsetWidth * window.devicePixelRatio;
    this._canvas.height = this.offsetHeight * window.devicePixelRatio;
    this.update();
  }

  get src() {
    return this._data.src;
  }

  set src(value) {
    this._data.src = value;

    const resizeCanvas = () => {
      this._data.removeEventListener("load", resizeCanvas);
      this.resize();
    }

    this._data.addEventListener("load", resizeCanvas);
  }

  addEventListener() {
    this._data.addEventListener(...arguments);
  }

  removeEventListener() {
    this._data.removeEventListener(...arguments);
  }
}

window.customElements.define("dlib-webglimg", WebGLImageElement);
<commit_msg>fix WebGLImageElement texture bind<commit_after>import GLMesh from "../gl/GLMesh.js";
import GLProgram from "../gl/GLProgram.js";
import GLTexture from "../gl/GLTexture.js";

let style = document.createElement("style");
style.textContent = `
  dlib-webglimage {
    display: block;
    position: relative;
  }
`;
document.head.appendChild(style);

export default class WebGLImageElement extends HTMLElement {
  constructor({
    tagName = "img"
  } = {}) {
    super();

    this._resizeBinded = this.resize.bind(this);

    this._data = document.createElement(tagName);
    this._canvas = document.createElement("canvas");
    this._canvas.style.width = "100%";
    this._canvas.style.height = "100%";
    this.appendChild(this._canvas);
    this.gl = this._canvas.getContext(WebGL2RenderingContext ? "webgl2" : "webgl", {
      premultipliedAlpha: false
    });

    this._mesh = new GLMesh({
      gl: this.gl,
      attributes: [
        ["position", {
          data: new Float32Array([
            -1, -1,
            -1, 1,
            1, -1,
            1, 1
          ]),
          size: 2
        }],
        ["uv", {
          data: new Float32Array([
            0, 1,
            0, 0,
            1, 1,
            1, 0
          ]),
          size: 2
        }]
      ]
    });

    this._texture = new GLTexture({
      gl: this.gl
    });
    this._texture.minFilter = this.gl.LINEAR;
    this._texture.wrapS = this._texture.wrapT = this.gl.CLAMP_TO_EDGE;

    this.program = new GLProgram({
      gl: this.gl,
      uniforms: [
        ["data", 0]
      ],
      vertexShader: `#version 300 es
        in vec2 position;
        in vec2 uv;

        out vec2 vUv;

        void main() {
          gl_Position = vec4(position, 0., 1.);
          vUv = uv;
        }
      `,
      fragmentShader: `#version 300 es
        precision highp float;

        uniform sampler2D data;

        in vec2 vUv;

        out vec4 fragColor;

        void main() {
          fragColor = texture(data, vUv);
          fragColor.rgb *= fragColor.a;
        }
      `
    });
    this.program.use();

    this.program.attributes.set(this._mesh.attributes);

    if(this.hasAttribute("src")) {
      this.src = this.getAttribute("src");
    }
  }

  connectedCallback() {
    window.addEventListener("resize", this._resizeBinded);
  }

  disconnectedCallback() {
    this.gl.getExtension("WEBGL_lose_context").loseContext();
    window.removeEventListener("resize", this._resizeBinded);
  }

  update() {
    this._texture.data = this._data;
    this.draw();
  }

  draw({
    width = this._canvas.width,
    height = this._canvas.height,
  } = {}) {
    this._texture.bind();
    this.gl.viewport(0, 0, width, height);
    this.gl.clearColor(0, 0, 0, 1);
    this.gl.clear(this.gl.COLOR_BUFFER_BIT);
    this._mesh.draw({
      mode: this.gl.TRIANGLE_STRIP,
      count: 4
    });
  }

  resize() {
    this._canvas.width = this.offsetWidth * window.devicePixelRatio;
    this._canvas.height = this.offsetHeight * window.devicePixelRatio;
    this.update();
  }

  get src() {
    return this._data.src;
  }

  set src(value) {
    this._data.src = value;

    const resizeCanvas = () => {
      this._data.removeEventListener("load", resizeCanvas);
      this.resize();
    }

    this._data.addEventListener("load", resizeCanvas);
  }

  addEventListener() {
    this._data.addEventListener(...arguments);
  }

  removeEventListener() {
    this._data.removeEventListener(...arguments);
  }
}

window.customElements.define("dlib-webglimg", WebGLImageElement);
<|endoftext|>


<commit_before>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// "http://microsoft-apiapp01371f9b84264eab9d5e506c9c4f6d24.azurewebsites.net/"
// "https://microsoft-apiapp01371f9b84264eab9d5e506c9c4f6d24.azurewebsites.net/"
//"http://localhost/FieldPromaxApi/"
var isInDevMode = true;
var constants = {
  fieldPromaxApi: isInDevMode ? "http://localhost:51518/" : "https://fieldpromax.azurewebsites.net/",
  localStorageKeys: {
    authorizationDataKey: "authorizationData", initialData: "initialData",
    storageKeyName: "authorizationData", configKeyName: "configurations", settingsKeyName: "userSettings", userCredentials: "userCredentials"
  }
};
var fpm = angular.module('fpm', ['ionic', 'ui.router', "LocalStorageModule", "ngCordova", "ionic-datepicker",
  "kendo.directives", "mobiscroll-datetime", "mobiscroll-timespan", "mobiscroll-numpad", "ui.rCalendar"])
  .config(["$stateProvider", "$urlRouterProvider", "$compileProvider", "$httpProvider", "$ionicConfigProvider",
    "ionicDatePickerProvider", "$provide", "fpm-utilities-factoryProvider", function ($stateProvider, $urlRouterProvider, $compileProvider,
      $httpProvider, $ionicConfigProvider, ionicDatePickerProvider, $provide, fpmUtilitiesFactoryProvider) {
      fpmUtilitiesFactoryProvider.setApplicationModel(isInDevMode);
      var routes = [
        { state: "login", config: { url: "/", controller: "login-controller", controllerAs: "vm", templateUrl: "views/login.html" } },
        { state: "app", config: { abstract: true, controller: "app-main-controller", controllerAs: "vm", templateUrl: "views/app-main.html" } },
        { state: "app.dashboard", config: { url: "/home?refresh", controller: "dashboard-controller", controllerAs: "vm", templateUrl: "views/dashboard.html" } },
        { state: "app.calendar", config: { url: "/calendar", controller: "calendar-controller", controllerAs: "vm", templateUrl: "views/calendar.html" } },
        { state: "app.map", config: { url: "/map", controller: "map-controller", controllerAs: "vm", templateUrl: "views/map.html" } },
        { state: "app.createWorkOrder", config: { url: "/createorder", controller: "create-order-controller", controllerAs: "vm", templateUrl: "views/create-order.html" } },
        {
          state: "app.editOrder", config: {
            url: "/editOrder?barCode&technicianNum&src", controller: "edit-order-controller", controllerAs: "vm", templateUrl: "views/edit-order.html"
          }
        },
        { state: "app.createCustomer", config: { url: "/createcustomer", controller: "create-customer-controller", controllerAs: "vm", templateUrl: "views/create-customer.html" } },
        { state: "app.createEstimate", config: { url: "/createestimate", controller: "create-estimate-controller", controllerAs: "vm", templateUrl: "views/create-estimate.html" } },
        { state: "app.expense", config: { url: "/expanses", controller: "expanses-controller", controllerAs: "vm", templateUrl: "views/expanses.html" } },
        { state: "app.timecard", config: { url: "/timecard", controller: "timecard-controller", controllerAs: "vm", templateUrl: "views/timecard.html" } },
        { state: "app.settings", config: { url: "/settings", controller: "settings-controller", controllerAs: "vm", templateUrl: "views/settings.html" } },
        { state: "app.changePassword", config: { url: "/changePassword", controller: "change-password-controller", controllerAs: "vm", templateUrl: "views/change-password.html" } },
        { state: "app.logout", config: { url: "/logout", controller: "logout-controller", controllerAs: "vm", templateUrl: "views/logout.html" } }
      ];

      angular.forEach(routes, function (route) {
        $stateProvider
          .state(route.state, route.config);
      });
      $urlRouterProvider.otherwise('/');
      $compileProvider.debugInfoEnabled(false);
      $httpProvider.interceptors.push("requestIntercepter");
      //DATE PICKER
      var datePickerObj = {
        inputDate: new Date(),
        setLabel: 'Set',
        todayLabel: 'Today',
        closeLabel: 'Close',
        mondayFirst: false,
        weeksList: ["S", "M", "T", "W", "T", "F", "S"],
        monthsList: ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"],
        templateType: 'popup',
        from: new Date(2012, 8, 1),
        to: new Date(2025, 8, 1),
        showTodayButton: true,
        dateFormat: 'dd MMMM yyyy',
        closeOnSelect: false,
      };
      ionicDatePickerProvider.configDatePicker(datePickerObj);

      //$ionicConfigProvider.tabs.position(isInDevMode ? 'top' : 'bottom');
      $ionicConfigProvider.tabs.position('bottom');

      //EXCPTION HANDLING
      $provide.decorator("$exceptionHandler", ["$delegate", "$injector", function ($delegate, $injector) {
        return function (exception, cause) {
          var data = {
            type: 'angular', url: window.location.hash, localtime: Date.now()
          };
          if (cause) { data.cause = cause; }
          if (exception) {
            if (exception.message) { data.message = exception.message; }
            if (exception.name) { data.name = exception.name; }
            if (exception.stack) { data.stack = exception.stack; }
          }
          console.log("EXCPTION", data);
        }
      }]);

    }])
  .run(["$ionicPlatform", "$rootScope", "$state", "$timeout", "fpm-utilities-factory", "authenticationFactory", "shared-data-factory",
    function ($ionicPlatform, $rootScope, $state, $timeout, fpmUtilitiesFactory, authenticationFactory, sharedDataFactory) {
      $ionicPlatform.ready(function () {
        if (window.cordova && window.cordova.plugins.Keyboard) {
          // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
          // for form inputs)
          cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);

          // Don't remove this line unless you know what you are doing. It stops the viewport
          // from snapping when text inputs are focused. Ionic handles this internally for
          // a much nicer keyboard experience.
          cordova.plugins.Keyboard.disableScroll(true);
        }
        if (window.StatusBar) {
          StatusBar.styleDefault();
        }
        //REGISTER FOR PUSH NOTIFICATIONS
        var isandr = fpmUtilitiesFactory.device.isAndroid();
        fpmUtilitiesFactory.push.register();
        document.addEventListener("backbutton", function (event) {
          if ($state.current.name === "app.dashboard") {
            //authenticationFactory.logout(false);
            if (navigator) navigator.app.exitApp();
          }
        }, false);

        function succesFn(location) {
          var credentials = authenticationFactory.getStoredCredentials();
          if (angular.isDefined(credentials) && location) {
            location.userId = credentials.userName;
            location.isMoving = location.is_moving;
            location.coords.altitudeAccuracy = location.coords.altitude_accuracy;
            sharedDataFactory.postLocation(location);
          }
        }

        if (!isInDevMode) {

          var bgGeo = window.BackgroundGeolocation;

          bgGeo.on("location", function (location, taskId) {
            succesFn(location);
          });

          bgGeo.on("motionchange", function (isMoving, location, taskId) {
            location.is_moving = isMoving;
            succesFn(location);
          });

          var lastActivity = "";

          bgGeo.on('activitychange', function (activityName) {
            if (lastActivity !== activityName) {
              lastActivity = activityName;
              BackgroundGeolocation.getCurrentPosition(function (location, taskId) {
                succesFn(location);
              }, errorFn, {
                  timeout: 30,      // 30 second timeout to fetch location
                  maximumAge: 5000, // Accept the last-known-location if not older than 5000 ms.
                  desiredAccuracy: 10,  // Try to fetch a location with an accuracy of `10` meters.
                });
            }
          });
        }
        function errorFn(errorCode) {
          switch (errorCode) {
            case 0:
              //fpmUtilitiesFactory.alerts.alert("ERROR 0", 'Failed to retrieve location');
              break;
            case 1:
              //fpmUtilitiesFactory.alerts.alert('ERROR 1', 'You must enable location services in Settings');
              break;
            case 2:
              //fpmUtilitiesFactory.alerts.alert('ERROR 2', 'Network Error');
              break;
            case 408:
              //fpmUtilitiesFactory.alerts.alert('ERROR 408', 'Location timeout');
              break;
          }
        }

        var androidLocationConfig = {
          desiredAccuracy: 0,
          stationaryRadius: 50,
          distanceFilter: 0,
          disableElasticity: true,
          locationUpdateInterval: 120000,
          activityRecognitionInterval: 60000,
          stopTimeout: 5,  // Stop-detection timeout minutes (wait x minutes to turn off tracking)
          debug: false, // <-- enable this hear sounds for background-geolocation life-cycle.
          logLevel: 5,    // Verbose logging.  0: NONE
          stopOnTerminate: true,              // <-- Don't stop tracking when user closes app.
          startOnBoot: true,
          autoSync: false
        };
        var iosConfig = {
          desiredAccuracy: 0,
          stationaryRadius: 50,
          distanceFilter: 100,
          disableElasticity: true,
          activityRecognitionInterval: 60000,
          stopTimeout: 5,  // Stop-detection timeout minutes (wait x minutes to turn off tracking)
          // Application config
          debug: false, // <-- enable this hear sounds for background-geolocation life-cycle.
          logLevel: 5,    // Verbose logging.  0: NONE
          stopOnTerminate: true,              // <-- Don't stop tracking when user closes app.
          startOnBoot: true,
          autoSync: false
        };
        var locationConfig = androidLocationConfig;
        if (!isandr) {
          locationConfig = iosConfig;
        }
        //TRY TO READ location
        function readLocation() {
          bgGeo.configure(locationConfig, function (state) {
            if (!state.enabled) {
              bgGeo.start();
            }
          });
        }
        if (!isInDevMode) {
          readLocation();
        }
      });
      //CHECK CONNECTION
      $rootScope.$on('$cordovaNetwork:online', function (event, networkState) {
        fpmUtilitiesFactory.hideNetworkDialog();
      });
      $rootScope.$on('$cordovaNetwork:offline', function (event, networkState) {
        fpmUtilitiesFactory.showNetworkDialog();
      });
    }]);

fpm.constant("fieldPromaxConfig", constants);
<commit_msg>updated<commit_after>// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// "http://microsoft-apiapp01371f9b84264eab9d5e506c9c4f6d24.azurewebsites.net/"
// "https://microsoft-apiapp01371f9b84264eab9d5e506c9c4f6d24.azurewebsites.net/"
//"http://localhost/FieldPromaxApi/"
var isInDevMode = false;
var constants = {
  fieldPromaxApi: isInDevMode ? "http://localhost:51518/" : "https://fieldpromax.azurewebsites.net/",
  localStorageKeys: {
    authorizationDataKey: "authorizationData", initialData: "initialData",
    storageKeyName: "authorizationData", configKeyName: "configurations", settingsKeyName: "userSettings", userCredentials: "userCredentials"
  }
};
var fpm = angular.module('fpm', ['ionic', 'ui.router', "LocalStorageModule", "ngCordova", "ionic-datepicker",
  "kendo.directives", "mobiscroll-datetime", "mobiscroll-timespan", "mobiscroll-numpad", "ui.rCalendar"])
  .config(["$stateProvider", "$urlRouterProvider", "$compileProvider", "$httpProvider", "$ionicConfigProvider",
    "ionicDatePickerProvider", "$provide", "fpm-utilities-factoryProvider", function ($stateProvider, $urlRouterProvider, $compileProvider,
      $httpProvider, $ionicConfigProvider, ionicDatePickerProvider, $provide, fpmUtilitiesFactoryProvider) {
      fpmUtilitiesFactoryProvider.setApplicationModel(isInDevMode);
      var routes = [
        { state: "login", config: { url: "/", controller: "login-controller", controllerAs: "vm", templateUrl: "views/login.html" } },
        { state: "app", config: { abstract: true, controller: "app-main-controller", controllerAs: "vm", templateUrl: "views/app-main.html" } },
        { state: "app.dashboard", config: { url: "/home?refresh", controller: "dashboard-controller", controllerAs: "vm", templateUrl: "views/dashboard.html" } },
        { state: "app.calendar", config: { url: "/calendar", controller: "calendar-controller", controllerAs: "vm", templateUrl: "views/calendar.html" } },
        { state: "app.map", config: { url: "/map", controller: "map-controller", controllerAs: "vm", templateUrl: "views/map.html" } },
        { state: "app.createWorkOrder", config: { url: "/createorder", controller: "create-order-controller", controllerAs: "vm", templateUrl: "views/create-order.html" } },
        {
          state: "app.editOrder", config: {
            url: "/editOrder?barCode&technicianNum&src", controller: "edit-order-controller", controllerAs: "vm", templateUrl: "views/edit-order.html"
          }
        },
        { state: "app.createCustomer", config: { url: "/createcustomer", controller: "create-customer-controller", controllerAs: "vm", templateUrl: "views/create-customer.html" } },
        { state: "app.createEstimate", config: { url: "/createestimate", controller: "create-estimate-controller", controllerAs: "vm", templateUrl: "views/create-estimate.html" } },
        { state: "app.expense", config: { url: "/expanses", controller: "expanses-controller", controllerAs: "vm", templateUrl: "views/expanses.html" } },
        { state: "app.timecard", config: { url: "/timecard", controller: "timecard-controller", controllerAs: "vm", templateUrl: "views/timecard.html" } },
        { state: "app.settings", config: { url: "/settings", controller: "settings-controller", controllerAs: "vm", templateUrl: "views/settings.html" } },
        { state: "app.changePassword", config: { url: "/changePassword", controller: "change-password-controller", controllerAs: "vm", templateUrl: "views/change-password.html" } },
        { state: "app.logout", config: { url: "/logout", controller: "logout-controller", controllerAs: "vm", templateUrl: "views/logout.html" } }
      ];

      angular.forEach(routes, function (route) {
        $stateProvider
          .state(route.state, route.config);
      });
      $urlRouterProvider.otherwise('/');
      $compileProvider.debugInfoEnabled(false);
      $httpProvider.interceptors.push("requestIntercepter");
      //DATE PICKER
      var datePickerObj = {
        inputDate: new Date(),
        setLabel: 'Set',
        todayLabel: 'Today',
        closeLabel: 'Close',
        mondayFirst: false,
        weeksList: ["S", "M", "T", "W", "T", "F", "S"],
        monthsList: ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"],
        templateType: 'popup',
        from: new Date(2012, 8, 1),
        to: new Date(2025, 8, 1),
        showTodayButton: true,
        dateFormat: 'dd MMMM yyyy',
        closeOnSelect: false,
      };
      ionicDatePickerProvider.configDatePicker(datePickerObj);

      //$ionicConfigProvider.tabs.position(isInDevMode ? 'top' : 'bottom');
      $ionicConfigProvider.tabs.position('bottom');

      //EXCPTION HANDLING
      $provide.decorator("$exceptionHandler", ["$delegate", "$injector", function ($delegate, $injector) {
        return function (exception, cause) {
          var data = {
            type: 'angular', url: window.location.hash, localtime: Date.now()
          };
          if (cause) { data.cause = cause; }
          if (exception) {
            if (exception.message) { data.message = exception.message; }
            if (exception.name) { data.name = exception.name; }
            if (exception.stack) { data.stack = exception.stack; }
          }
          console.log("EXCPTION", data);
        }
      }]);

    }])
  .run(["$ionicPlatform", "$rootScope", "$state", "$timeout", "fpm-utilities-factory", "authenticationFactory", "shared-data-factory",
    function ($ionicPlatform, $rootScope, $state, $timeout, fpmUtilitiesFactory, authenticationFactory, sharedDataFactory) {
      $ionicPlatform.ready(function () {
        if (window.cordova && window.cordova.plugins.Keyboard) {
          // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
          // for form inputs)
          cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);

          // Don't remove this line unless you know what you are doing. It stops the viewport
          // from snapping when text inputs are focused. Ionic handles this internally for
          // a much nicer keyboard experience.
          cordova.plugins.Keyboard.disableScroll(true);
        }
        if (window.StatusBar) {
          StatusBar.styleDefault();
        }
        //REGISTER FOR PUSH NOTIFICATIONS
        var isandr = fpmUtilitiesFactory.device.isAndroid();
        fpmUtilitiesFactory.push.register();
        document.addEventListener("backbutton", function (event) {
          if ($state.current.name === "app.dashboard") {
            //authenticationFactory.logout(false);
            if (navigator) navigator.app.exitApp();
          }
        }, false);

        function succesFn(location) {
          var credentials = authenticationFactory.getStoredCredentials();
          if (angular.isDefined(credentials) && location) {
            location.userId = credentials.userName;
            location.isMoving = location.is_moving;
            location.coords.altitudeAccuracy = location.coords.altitude_accuracy;
            sharedDataFactory.postLocation(location);
          }
        }

        if (!isInDevMode) {

          var bgGeo = window.BackgroundGeolocation;

          bgGeo.on("location", function (location, taskId) {
            succesFn(location);
          });

          bgGeo.on("motionchange", function (isMoving, location, taskId) {
            location.is_moving = isMoving;
            succesFn(location);
          });

          var lastActivity = "";

          bgGeo.on('activitychange', function (activityName) {
            if (lastActivity !== activityName) {
              lastActivity = activityName;
              BackgroundGeolocation.getCurrentPosition(function (location, taskId) {
                succesFn(location);
              }, errorFn, {
                  timeout: 30,      // 30 second timeout to fetch location
                  maximumAge: 5000, // Accept the last-known-location if not older than 5000 ms.
                  desiredAccuracy: 10,  // Try to fetch a location with an accuracy of `10` meters.
                });
            }
          });
        }
        function errorFn(errorCode) {
          switch (errorCode) {
            case 0:
              //fpmUtilitiesFactory.alerts.alert("ERROR 0", 'Failed to retrieve location');
              break;
            case 1:
              //fpmUtilitiesFactory.alerts.alert('ERROR 1', 'You must enable location services in Settings');
              break;
            case 2:
              //fpmUtilitiesFactory.alerts.alert('ERROR 2', 'Network Error');
              break;
            case 408:
              //fpmUtilitiesFactory.alerts.alert('ERROR 408', 'Location timeout');
              break;
          }
        }

        var androidLocationConfig = {
          desiredAccuracy: 0,
          stationaryRadius: 50,
          distanceFilter: 0,
          disableElasticity: true,
          locationUpdateInterval: 120000,
          activityRecognitionInterval: 60000,
          stopTimeout: 5,  // Stop-detection timeout minutes (wait x minutes to turn off tracking)
          debug: false, // <-- enable this hear sounds for background-geolocation life-cycle.
          logLevel: 5,    // Verbose logging.  0: NONE
          stopOnTerminate: true,              // <-- Don't stop tracking when user closes app.
          startOnBoot: true,
          autoSync: false
        };
        var iosConfig = {
          desiredAccuracy: 0,
          stationaryRadius: 50,
          distanceFilter: 100,
          disableElasticity: true,
          activityRecognitionInterval: 60000,
          stopTimeout: 5,  // Stop-detection timeout minutes (wait x minutes to turn off tracking)
          // Application config
          debug: false, // <-- enable this hear sounds for background-geolocation life-cycle.
          logLevel: 5,    // Verbose logging.  0: NONE
          stopOnTerminate: true,              // <-- Don't stop tracking when user closes app.
          startOnBoot: true,
          autoSync: false
        };
        var locationConfig = androidLocationConfig;
        if (!isandr) {
          locationConfig = iosConfig;
        }
        //TRY TO READ location
        function readLocation() {
          bgGeo.configure(locationConfig, function (state) {
            if (!state.enabled) {
              bgGeo.start();
            }
          });
        }
        if (!isInDevMode) {
          readLocation();
        }
      });
      //CHECK CONNECTION
      $rootScope.$on('$cordovaNetwork:online', function (event, networkState) {
        fpmUtilitiesFactory.hideNetworkDialog();
      });
      $rootScope.$on('$cordovaNetwork:offline', function (event, networkState) {
        fpmUtilitiesFactory.showNetworkDialog();
      });
    }]);

fpm.constant("fieldPromaxConfig", constants);
<|endoftext|>