<commit_before>Stories = new Mongo.Collection('stories');

// Create a schema for the stories collection.
Schema = {};
Schema.stories = new SimpleSchema({
  author:{
    type: String,
    label: "Author",
    max: 100,
    optional: true
  },
  content:{
    type: String,
    label: "Content",
    max: 10000
  },
  createdAt: {
    type: Date,
    label: "Posted on",
    denyUpdate: true
  }
});

// Attach the schema to the stories collection.
Stories.attachSchema(Schema.stories);

// Create pagination for displaying the stories.
this.Pages = new Meteor.Pagination(Stories, {
  itemTemplate: "storyItem", // the template to display a story
  perPage: 5,
  sort: {
    submitted: -1
  }
});

Meteor.methods({
  storyInsert: function (doc) {// storyInsert gets called by the autoform
    // Get and verify reCaptcha.
    var reCaptchaResponse = ServerSession.get('reCaptchaResponse');
    var verifyCaptchaResponse = reCAPTCHA.verifyCaptcha(this.connection.clientAddress, reCaptchaResponse);
    // This last line gives errors. For more infos, see:
    // https://forums.meteor.com/t/all-my-trials-to-get-to-the-client-ip-address-are-leading-to-undefined/3219
    // Maybe something here could help fixing it : https://github.com/mizzao/meteor-user-status/issues/50

    if( verifyCaptchaResponse.data.success === false ){
      console.log('reCAPTCHA check failed!', verifyCaptchaResponse);
      return verifyCaptchaResponse.data;
    };

    console.log('reCAPTCHA verification passed!');
    // Doing clean first adds the date autovalue and fixes this error:
    //   Exception while invoking method 'storyInsert' Error: Match error:
    //   One or more properties do not match the schema.
    Schema.stories.clean(doc);
    // server-side check for security and data integrity
    check(doc, Schema.stories);

    var storyId = Stories.insert(doc);

    return true;
  }
});<commit_msg>Fixed the order in which stories are displayed<commit_after>Stories = new Mongo.Collection('stories');

// Create a schema for the stories collection.
Schema = {};
Schema.stories = new SimpleSchema({
  author:{
    type: String,
    label: "Author",
    max: 100,
    optional: true
  },
  content:{
    type: String,
    label: "Content",
    max: 10000
  },
  createdAt: {
    type: Date,
    label: "Posted on",
    denyUpdate: true
  }
});

// Attach the schema to the stories collection.
Stories.attachSchema(Schema.stories);

// Create pagination for displaying the stories.
this.Pages = new Meteor.Pagination(Stories, {
  itemTemplate: "storyItem", // the template to display a story
  perPage: 5,
  sort: {
    createdAt: -1
  }
});

Meteor.methods({
  storyInsert: function (doc) {// storyInsert gets called by the autoform
    // Get and verify reCaptcha.
    var reCaptchaResponse = ServerSession.get('reCaptchaResponse');
    var verifyCaptchaResponse = reCAPTCHA.verifyCaptcha(this.connection.clientAddress, reCaptchaResponse);
    // This last line gives errors. For more infos, see:
    // https://forums.meteor.com/t/all-my-trials-to-get-to-the-client-ip-address-are-leading-to-undefined/3219
    // Maybe something here could help fixing it : https://github.com/mizzao/meteor-user-status/issues/50

    if( verifyCaptchaResponse.data.success === false ){
      console.log('reCAPTCHA check failed!', verifyCaptchaResponse);
      return verifyCaptchaResponse.data;
    };

    console.log('reCAPTCHA verification passed!');
    // Doing clean first adds the date autovalue and fixes this error:
    //   Exception while invoking method 'storyInsert' Error: Match error:
    //   One or more properties do not match the schema.
    Schema.stories.clean(doc);
    // server-side check for security and data integrity
    check(doc, Schema.stories);

    var storyId = Stories.insert(doc);

    return true;
  }
});<|endoftext|>


<commit_before>'use strict';

var Zermelo = require('../index.js');

function validUnix(unixTimestamp) {
  var date = new Date(unixTimestamp);
  console.log(date instanceof Date && !isNaN(date.valueOf()));
}

Zermelo.prototype.getSchedule = function (unixStart, unixEnd, callback) {
  unixStart = Math.round(parseInt(unixStart));
  unixEnd = Math.round(parseInt(unixEnd));

  validUnix(unixStart);

  if (isNaN(unixStart) || !validUnix(unixStart)) {
    return callback('Invalid UNIX at Start Time');
  }
  else if (isNaN(unixEnd) || !validUnix(unixEnd)) {
    return callback('Invalid UNIX at End Time');
  }

  var data = {
    'start': unixStart,
    'end': unixEnd,
    'user': '~me',
    'access_token': this._token
  };

  this.Get('appointments', data, function (err, res) {
    if (err) {
      return callback(err, null);
    }

    (res.data).sort((a, b) => { return a.start - b.start; });
    return callback(null, res);
  });
};
<commit_msg>Improved Unix Validator 2<commit_after>'use strict';

var Zermelo = require('../index.js');

function validUnix(unixTimestamp) {
  var date = new Date(unixTimestamp);
  return (date instanceof Date && !isNaN(date.valueOf()));
}

Zermelo.prototype.getSchedule = function (unixStart, unixEnd, callback) {
  unixStart = Math.round(parseInt(unixStart));
  unixEnd = Math.round(parseInt(unixEnd));

  if (isNaN(unixStart) || !validUnix(unixStart)) {
    return callback('Invalid UNIX at Start Time');
  }
  else if (isNaN(unixEnd) || !validUnix(unixEnd)) {
    return callback('Invalid UNIX at End Time');
  }

  var data = {
    'start': unixStart,
    'end': unixEnd,
    'user': '~me',
    'access_token': this._token
  };

  this.Get('appointments', data, function (err, res) {
    if (err) {
      return callback(err, null);
    }

    (res.data).sort((a, b) => { return a.start - b.start; });
    return callback(null, res);
  });
};
<|endoftext|>


<commit_before>let _ = require('lodash');
let CrawlerFactory = require('../factory/crawler');
let CurrencyCrawler = require('../crawlers/currency');
let scheduler = require('node-schedule');

const crawlTypes = [
  'DiveDice', 'BoardLife', /*'BoardM', robots.txt disallowed me :(*/
  'BoardPia', 'Amazon', 'CardCastle', 'Cardhaus',
  'CoolStuffInc', 'MiniatureMarket', 'PopcornEdu'
];

function CrawlerController(managers) {
  this.currencyCrawler = new CurrencyCrawler();
  this.gameMgr = managers.game;
  this.userMgr = managers.user;
  this.postMgr = managers.post;
  this.crawlers = [];
  this.jobs = [];
  this.currencyJob = null;
};

CrawlerController.prototype.getCrawlers = function () {
  return this.crawlers;
};

CrawlerController.prototype.addCrawler = function (crawlerType) {
  if (true === _.isUndefined(_.find(this.crawlers, (el) => {
    return el.getType() === crawlerType;
  }))) {
    if (false === _.isUndefined(_.find(crawlTypes, (type) => {
      return type === crawlerType;
    }))) {
      // available type
      this.crawlers.push(CrawlerFactory(crawlerType));
    } else {
      console.error(`Requested Crawler ${crawlerType} is not available`);
    }
  } else {
    // crawler exists;
    console.log(`Crawler ${crawlerType} already exists`);
  }
  return crawlerType;
};

CrawlerController.prototype.removeCrawler = function (crawlerType) {
  // TODO::
  // if (true === _.isUndefined(_.find(this.crawlers, (el) => {
  //   return el.getType() === crawlerType;
  // }))) {
  //   if (false === _.isUndefined(_.find(crawlTypes, (type) => {
  //     return type === crawlerType;
  //   }))) {
  //     // available type
  //     this.crawlers.push(CrawlerFactory(crawlerType));
  //   } else {
  //     console.error(`Requested Crawler ${crawlerType} is not available`);
  //   }
  // } else {
  //   // crawler exists;
  //   console.log(`Crawler ${crawlerType} already exists`);
  // }
  return crawlerType;
};

CrawlerController.prototype.doCrawl = function (jobtype, crawlFunc, arg) {
  console.log(`Start crawling ${crawlFunc}`);

  let promises = _.filter(this.crawlers, (crawler) => {
    return crawler.canCrawl(jobtype);
  }).map((crawler) => {
    let ret = null;
    try {
      if (typeof crawler[crawlFunc] === 'function') {
        console.log(`Crawling ${crawlFunc} using ${crawler.getType()} crawler`);
        ret = crawler[crawlFunc].call(crawler, arg);
      }
    } catch (e) {
      console.error(`${e.message}`);
    }
    return ret;
  });

  return Promise.all(promises);
};

/**
 * interval in seconds
 * chainedFunc - (crawlResult[]): Promise<>
 * TODO:: direct crawler logs into different buckets...
 */
CrawlerController.prototype.scheduleCrawler = function (jobtype, crawlFunc, interval, chainedFunc, args) {
  let rule = new scheduler.RecurrenceRule();
  rule.second = interval;

  let job = scheduler.scheduleJob(rule, function () {
    this.doCrawl(jobtype, crawlFunc, args)
      .then(function (results) {
        chainedFunc(_.flatten(results));
      }.bind(this))
      .catch((err) => {
        console.error(`Error occured ${err.message}`);
      });
  }.bind(this));
  this.jobs.push({ crawlFunc, job });
  return job;
};

CrawlerController.prototype.scheduleCurrency = function (interval) {
  if (!_.isNull(this.currencyJob)) {
    throw new Error('Currency Job is already running');
  }

  let rule = new scheduler.RecurrenceRule();
  rule.second = interval;

  let job = scheduler.scheduleJob(rule, function () {
    this.currencyCrawler.crawlCurrency()
      .then(function () { }.bind(this))
      .catch((err) => {
        console.error(`Error occured ${err.message}`);
      });
  }.bind(this));
  this.currencyJob = job;
  return job;
};

CrawlerController.prototype.cancelCurrency = function () {
  if (_.isNull(this.currencyJob)) {
    throw new Error('Currency Job is not currently running');
  }

  this.currencyJob.cancle();
  this.currencyJob = null;

  return;
};

CrawlerController.prototype.getJobInfo = function (jobtype) {
  return new Promise(function (resolve, reject) {
    let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
    let chainedFunc = this.getChainedFuncFromJobType(jobtype);
    this.getAdditionalArgsFromJobType(jobtype).then((argsGot) => {
      args = argsGot;

      resolve({
        crawlFunc: targetCrawlFunc,
        chainedFunc,
        args
      });
    });

  }.bind(this));
};

CrawlerController.prototype.getChainedFuncFromJobType = function (jobtype) {
  let chainedFunc = null;

  switch (jobtype) {
    case 'price': {
      chainedFunc = function (prices) {
        return Promise.all(_.map(prices, function (price) {
          return this.gameMgr.addPrice.call(this.gameMgr, price)
        }.bind(this)))
          .then((uploaded) => { console.log(`${JSON.stringify(uploaded)}`); })
          .catch((err) => { console.log(`${err.message}`); });
      }.bind(this);
      break;
    }
    case 'post': {
      chainedFunc = function (posts) {
        return Promise.all(_.map(posts, function (post) {
          return this.postMgr.addPost.call(this.postMgr, post);
        }.bind(this)))
          .then((uploadedposts) => { console.log(`${JSON.stringify(uploadedposts)}`) })
          .catch((err) => { console.log(`${err.message}`) });
      }.bind(this);
      break;
    }
    default: {
      throw new Error('unexpected job type')
      break;
    }
  }

  return chainedFunc;
};

CrawlerController.prototype.getAdditionalArgsFromJobType = function (jobtype) {
  return new Promise(function (resolve, reject) {
    switch (jobtype) {
      case 'price': {
        resolve({
          gameManager: this.gameMgr,
          currencyCrawler: this.currencyCrawler
        });
        break;
      }
      case 'post': {
        resolve({
        });
        break;
      }
      default: {
        throw new Error('unexpected job type')
        break;
      }
    }
  }.bind(this));
};

CrawlerController.prototype.getCrawlFuncFromJobType = function (jobtype) {
  let targetCrawlFunc = null;

  switch (jobtype) {
    case 'price': {
      targetCrawlFunc = 'getGamesPrice';
      break;
    }
    case 'post': {
      targetCrawlFunc = 'crawlList';
      break;
    }
    default: {
      throw new Error('unexpected job type')
      break;
    }
  }

  return targetCrawlFunc;
};

CrawlerController.prototype.isJobRunning = function (jobtype) {
  let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
  let filtered = _.filter(this.jobs, (job) => {
    return job.crawlFunc === targetCrawlFunc;
  })
  return filtered.length !== 0;
}

CrawlerController.prototype.cancelCrawler = function (jobtype) {
  let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
  let filtered = _.filter(this.jobs, (job) => {
    return job.crawlFunc === targetCrawlFunc;
  })
  _.forEach(filtered, (job) => {
    job.job.cancel();
  });
  _.pullAll(this.jobs, filtered);
  if (filtered.length === 0) {
    throw new Error(`No Crawl Job ${jobtype} was found to cancel`);
  }
}

CrawlerController.prototype.cancelCrawlers = function () {
  _.forEach(this.jobs, (job) => {
    job.job.cancel();
  });
  this.jobs = [];
};

module.exports = CrawlerController;<commit_msg>fix scheduler issue<commit_after>let _ = require('lodash');
let CrawlerFactory = require('../factory/crawler');
let CurrencyCrawler = require('../crawlers/currency');
let scheduler = require('node-schedule');

const crawlTypes = [
  'DiveDice', 'BoardLife', /*'BoardM', robots.txt disallowed me :(*/
  'BoardPia', 'Amazon', 'CardCastle', 'Cardhaus',
  'CoolStuffInc', 'MiniatureMarket', 'PopcornEdu'
];

function CrawlerController(managers) {
  this.currencyCrawler = new CurrencyCrawler();
  this.gameMgr = managers.game;
  this.userMgr = managers.user;
  this.postMgr = managers.post;
  this.crawlers = [];
  this.jobs = [];
  this.currencyJob = null;
};

CrawlerController.prototype.getCrawlers = function () {
  return this.crawlers;
};

CrawlerController.prototype.addCrawler = function (crawlerType) {
  if (true === _.isUndefined(_.find(this.crawlers, (el) => {
    return el.getType() === crawlerType;
  }))) {
    if (false === _.isUndefined(_.find(crawlTypes, (type) => {
      return type === crawlerType;
    }))) {
      // available type
      this.crawlers.push(CrawlerFactory(crawlerType));
    } else {
      console.error(`Requested Crawler ${crawlerType} is not available`);
    }
  } else {
    // crawler exists;
    console.log(`Crawler ${crawlerType} already exists`);
  }
  return crawlerType;
};

CrawlerController.prototype.removeCrawler = function (crawlerType) {
  // TODO::
  // if (true === _.isUndefined(_.find(this.crawlers, (el) => {
  //   return el.getType() === crawlerType;
  // }))) {
  //   if (false === _.isUndefined(_.find(crawlTypes, (type) => {
  //     return type === crawlerType;
  //   }))) {
  //     // available type
  //     this.crawlers.push(CrawlerFactory(crawlerType));
  //   } else {
  //     console.error(`Requested Crawler ${crawlerType} is not available`);
  //   }
  // } else {
  //   // crawler exists;
  //   console.log(`Crawler ${crawlerType} already exists`);
  // }
  return crawlerType;
};

CrawlerController.prototype.doCrawl = function (jobtype, crawlFunc, arg) {
  console.log(`Start crawling ${crawlFunc}`);

  let promises = _.filter(this.crawlers, (crawler) => {
    return crawler.canCrawl(jobtype);
  }).map((crawler) => {
    let ret = null;
    try {
      if (typeof crawler[crawlFunc] === 'function') {
        console.log(`Crawling ${crawlFunc} using ${crawler.getType()} crawler`);
        ret = crawler[crawlFunc].call(crawler, arg);
      }
    } catch (e) {
      console.error(`${e.message}`);
    }
    return ret;
  });

  return Promise.all(promises);
};

/**
 * interval in seconds
 * chainedFunc - (crawlResult[]): Promise<>
 * TODO:: direct crawler logs into different buckets...
 */
CrawlerController.prototype.scheduleCrawler = function (jobtype, crawlFunc, interval, chainedFunc, args) {
  let rule = new scheduler.RecurrenceRule();
  rule.hour = Math.floor(interval / 3600);
  rule.second = interval % 60;
  rule.minute = Math.floor((interval - rule.hour * 3600) / 60);

  let job = scheduler.scheduleJob(rule, function () {
    this.doCrawl(jobtype, crawlFunc, args)
      .then(function (results) {
        chainedFunc(_.flatten(results));
      }.bind(this))
      .catch((err) => {
        console.error(`Error occured ${err.message}`);
      });
  }.bind(this));
  this.jobs.push({ crawlFunc, job });
  return job;
};

CrawlerController.prototype.scheduleCurrency = function (interval) {
  if (!_.isNull(this.currencyJob)) {
    throw new Error('Currency Job is already running');
  }

  let rule = new scheduler.RecurrenceRule();
  rule.second = interval;

  let job = scheduler.scheduleJob(rule, function () {
    this.currencyCrawler.crawlCurrency()
      .then(function () { }.bind(this))
      .catch((err) => {
        console.error(`Error occured ${err.message}`);
      });
  }.bind(this));
  this.currencyJob = job;
  return job;
};

CrawlerController.prototype.cancelCurrency = function () {
  if (_.isNull(this.currencyJob)) {
    throw new Error('Currency Job is not currently running');
  }

  this.currencyJob.cancle();
  this.currencyJob = null;

  return;
};

CrawlerController.prototype.getJobInfo = function (jobtype) {
  return new Promise(function (resolve, reject) {
    let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
    let chainedFunc = this.getChainedFuncFromJobType(jobtype);
    this.getAdditionalArgsFromJobType(jobtype).then((argsGot) => {
      args = argsGot;

      resolve({
        crawlFunc: targetCrawlFunc,
        chainedFunc,
        args
      });
    });

  }.bind(this));
};

CrawlerController.prototype.getChainedFuncFromJobType = function (jobtype) {
  let chainedFunc = null;

  switch (jobtype) {
    case 'price': {
      chainedFunc = function (prices) {
        return Promise.all(_.map(prices, function (price) {
          return this.gameMgr.addPrice.call(this.gameMgr, price)
        }.bind(this)))
          .then((uploaded) => { console.log(`${JSON.stringify(uploaded)}`); })
          .catch((err) => { console.log(`${err.message}`); });
      }.bind(this);
      break;
    }
    case 'post': {
      chainedFunc = function (posts) {
        return Promise.all(_.map(posts, function (post) {
          return this.postMgr.addPost.call(this.postMgr, post);
        }.bind(this)))
          .then((uploadedposts) => { console.log(`${JSON.stringify(uploadedposts)}`) })
          .catch((err) => { console.log(`${err.message}`) });
      }.bind(this);
      break;
    }
    default: {
      throw new Error('unexpected job type')
      break;
    }
  }

  return chainedFunc;
};

CrawlerController.prototype.getAdditionalArgsFromJobType = function (jobtype) {
  return new Promise(function (resolve, reject) {
    switch (jobtype) {
      case 'price': {
        resolve({
          gameManager: this.gameMgr,
          currencyCrawler: this.currencyCrawler
        });
        break;
      }
      case 'post': {
        resolve({
        });
        break;
      }
      default: {
        throw new Error('unexpected job type')
        break;
      }
    }
  }.bind(this));
};

CrawlerController.prototype.getCrawlFuncFromJobType = function (jobtype) {
  let targetCrawlFunc = null;

  switch (jobtype) {
    case 'price': {
      targetCrawlFunc = 'getGamesPrice';
      break;
    }
    case 'post': {
      targetCrawlFunc = 'crawlList';
      break;
    }
    default: {
      throw new Error('unexpected job type')
      break;
    }
  }

  return targetCrawlFunc;
};

CrawlerController.prototype.isJobRunning = function (jobtype) {
  let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
  let filtered = _.filter(this.jobs, (job) => {
    return job.crawlFunc === targetCrawlFunc;
  })
  return filtered.length !== 0;
}

CrawlerController.prototype.cancelCrawler = function (jobtype) {
  let targetCrawlFunc = this.getCrawlFuncFromJobType(jobtype);
  let filtered = _.filter(this.jobs, (job) => {
    return job.crawlFunc === targetCrawlFunc;
  })
  _.forEach(filtered, (job) => {
    job.job.cancel();
  });
  _.pullAll(this.jobs, filtered);
  if (filtered.length === 0) {
    throw new Error(`No Crawl Job ${jobtype} was found to cancel`);
  }
}

CrawlerController.prototype.cancelCrawlers = function () {
  _.forEach(this.jobs, (job) => {
    job.job.cancel();
  });
  this.jobs = [];
};

module.exports = CrawlerController;<|endoftext|>


<commit_before>var modulus = require('../modulus'),
    librarian = require('../common/api').librarian,
    userConfig = require('../common/api').userConfig,
    fs = require('fs'),
    ProgressBar = require('progress'),
    Progress = require('../util/progress'),
    request = require('request');

var Project = function() {

};

Project.prototype.create = function(name, creatorId, callback) {
  librarian.project.create({
    name: name,
    creator: creatorId
  }, userConfig.data.apiKey, callback);
};

Project.prototype.find = function(opts, callback) {
  librarian.project.find(opts, userConfig.data.apiKey, callback);
};

Project.prototype.saveVars = function(projectId, vars, callback) {
  librarian.project.saveVars(projectId, vars, userConfig.data.apiKey, callback);
};

Project.prototype.deploy = function(projectId, file, callback) {
  var host = librarian._http._host;
  var port = librarian._http._port;

  var url = host + ':' + port;
  var protocol = librarian._http._ssl ? 'https' : 'http';
  var endpoint = protocol + '://' + url + '/project/deploy/' + projectId + '?authToken=' + userConfig.data.apiKey;

  modulus.io.print('Uploading project...');
  var status = Project.status.uploading;

  fs.stat(file, function(err, stat) {
    fs.createReadStream(file).pipe(
      request.put(
        {
          method: 'PUT',
          uri : endpoint,
          headers : {
            'content-length' : stat.size
          }
        },
        function(err, res, b) {
          if(err) {
            callback(err);
          }
        }
      )
    );

    // start checking for status changes
    // show progress for upload and inderminate progress for deploying
    var ubar = new ProgressBar('Upload progress [:bar] :percent', {
        complete: '=',
        incomplete: ' ',
        width: 20,
        total: stat.size
    });
    ubar.tick();
    var uploadTimeout = null;
    var uploadProgress = function() {
      librarian.project.uploadProgress(projectId, userConfig.data.apiKey, function(err, p) {
        if(err) {
          setTimeout(uploadProgress, 100);
          return;
        }
        ubar.tick(p.bytesReceived - ubar.curr);
        if(p.bytesReceived < stat.size && status === Project.status.uploading) {
          uploadTimeout = setTimeout(uploadProgress, 200);
        }
      });
    };
    uploadTimeout = setTimeout(uploadProgress, 500);

    var dbar = new Progress.indeterminate('Deploying [:bar]');

    // check every second for project status change
    var projectStatus = function () {
      librarian.project.find({projectId : projectId}, userConfig.data.apiKey, function(err, proj) {
        if(proj.status.toLowerCase() !== status) {
          var newStatus = proj.status.toLowerCase();
          if(newStatus === Project.status.deploying) {
            status = newStatus;
            clearTimeout(uploadTimeout);
            ubar.tick(stat.size);
            modulus.io.print('\nDeploying Project...');
            dbar.start();
          } else if(newStatus === Project.status.running && status !== Project.status.uploading) {
            dbar.stop();
            modulus.io.print(' ');
            return callback(null);
          }
        }
        if(status !== Project.status.running) {
          setTimeout(projectStatus, 1000);
        }
      });
    };
    projectStatus();
  });
};

Project.status = {
  uploading : 'uploading',
  deploying : 'deploying',
  running : 'running'
};

module.exports = new Project();<commit_msg>Fixed the params passed on the project create call.<commit_after>var modulus = require('../modulus'),
    librarian = require('../common/api').librarian,
    userConfig = require('../common/api').userConfig,
    fs = require('fs'),
    ProgressBar = require('progress'),
    Progress = require('../util/progress'),
    request = require('request');

var Project = function() {

};

Project.prototype.create = function(name, creatorId, callback) {
  librarian.project.create({
    name: name,
    creator: creatorId
  }, false, userConfig.data.apiKey, callback);
};

Project.prototype.find = function(opts, callback) {
  librarian.project.find(opts, userConfig.data.apiKey, callback);
};

Project.prototype.saveVars = function(projectId, vars, callback) {
  librarian.project.saveVars(projectId, vars, userConfig.data.apiKey, callback);
};

Project.prototype.deploy = function(projectId, file, callback) {
  var host = librarian._http._host;
  var port = librarian._http._port;

  var url = host + ':' + port;
  var protocol = librarian._http._ssl ? 'https' : 'http';
  var endpoint = protocol + '://' + url + '/project/deploy/' + projectId + '?authToken=' + userConfig.data.apiKey;

  modulus.io.print('Uploading project...');
  var status = Project.status.uploading;

  fs.stat(file, function(err, stat) {
    fs.createReadStream(file).pipe(
      request.put(
        {
          method: 'PUT',
          uri : endpoint,
          headers : {
            'content-length' : stat.size
          }
        },
        function(err, res, b) {
          if(err) {
            callback(err);
          }
        }
      )
    );

    // start checking for status changes
    // show progress for upload and inderminate progress for deploying
    var ubar = new ProgressBar('Upload progress [:bar] :percent', {
        complete: '=',
        incomplete: ' ',
        width: 20,
        total: stat.size
    });
    ubar.tick();
    var uploadTimeout = null;
    var uploadProgress = function() {
      librarian.project.uploadProgress(projectId, userConfig.data.apiKey, function(err, p) {
        if(err) {
          setTimeout(uploadProgress, 100);
          return;
        }
        ubar.tick(p.bytesReceived - ubar.curr);
        if(p.bytesReceived < stat.size && status === Project.status.uploading) {
          uploadTimeout = setTimeout(uploadProgress, 200);
        }
      });
    };
    uploadTimeout = setTimeout(uploadProgress, 500);

    var dbar = new Progress.indeterminate('Deploying [:bar]');

    // check every second for project status change
    var projectStatus = function () {
      librarian.project.find({projectId : projectId}, userConfig.data.apiKey, function(err, proj) {
        if(proj.status.toLowerCase() !== status) {
          var newStatus = proj.status.toLowerCase();
          if(newStatus === Project.status.deploying) {
            status = newStatus;
            clearTimeout(uploadTimeout);
            ubar.tick(stat.size);
            modulus.io.print('\nDeploying Project...');
            dbar.start();
          } else if(newStatus === Project.status.running && status !== Project.status.uploading) {
            dbar.stop();
            modulus.io.print(' ');
            return callback(null);
          }
        }
        if(status !== Project.status.running) {
          setTimeout(projectStatus, 1000);
        }
      });
    };
    projectStatus();
  });
};

Project.status = {
  uploading : 'uploading',
  deploying : 'deploying',
  running : 'running'
};

module.exports = new Project();<|endoftext|>


<commit_before>Iris
    .controller('CalendarCtrl', function($scope,$http,$timeout,$compile,uiCalendarConfig,irisAPIUrl,RootFactory) {
        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();
        // var tz = date.getTimezoneOffset();
        // console.log("time offset", tz)
        $scope.noteBox = '';
        $scope.events = [];

        RootFactory.getApiRoot()
            .then(
            root => {
                $http.get(`${root.notes}`)
                    .then(res => {
                        console.log("notes res: ", res.data );
                        $scope.populateCalendar(res);
                        $scope.notes= res.data;
                });
                $timeout();
            },
            err => console.log('error', err)
            ).then(
                $timeout //forces scope apply to DOM - reapply everything
            );

        $scope.populateCalendar = function (notes) {
            notes.data.forEach( (note) => {
                $scope.events.push({note_id: note.id, title: note.note_content, start: new Date(note.note_date)})
            })
            // console.log($scope.events)
        }

        $scope.addToCalendar = function(noteInfo, selectedDate){
            console.log(selectedDate)
            $http.post(`${irisAPIUrl}/notes/`, {note_content: noteInfo,note_date: selectedDate})
              .then(res => {
                  $scope.events.push({title: res.data.note_content, start: new Date(res.data.note_date)})
                console.log("res notes: ", res );
                console.log("events", $scope.events)
                $timeout()
              });
        }

        // $scope.changeTo = 'Hungarian';
        /* event source that pulls from google.com */
        // $scope.eventSource = {
        //         url: "http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
        //         className: 'gcal-event',           // an option!
        //         currentTimezone: 'America/Chicago' // an option!
        // };
        /* event source that contains custom events on the scope */
        // $scope.events = [];
        //   {title: 'All Day Event',start: new Date(y, m, 1)},
        //   {title: 'Long Event',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)},
        //   {id: 999,title: 'Repeating Event',start: new Date(y, m, d - 3, 16, 0),allDay: false},
        //   {id: 999,title: 'Repeating Event',start: new Date(y, m, d + 4, 16, 0),allDay: false},
        //   {title: 'Birthday Party',start: new Date(y, m, d + 1, 19, 0),end: new Date(y, m, d + 1, 22, 30),allDay: false},
        //   {title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}

        /* event source that calls a function on every view switch */
        $scope.eventsF = function (start, end, timezone, callback) {
        //   var s = new Date(start).getTime() / 1000;
        //   var e = new Date(end).getTime() / 1000;
        //   var m = new Date(start).getMonth();
        //   var events = [{title: 'Feed Me ' + m,start: s + (50000),end: s + (100000),allDay: false, className: ['customFeed']}];
          callback($scope.events);
        };

        // $scope.calEventsExt = {
        //    color: '#f00',
        //    textColor: 'yellow',
        //    events: [
        //       {type:'party',title: 'Lunch',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
        //       {type:'party',title: 'Lunch 2',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
        //       {type:'party',title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}
        //     ]
        // };
        /* alert on eventClick */
        $scope.alertOnEventClick = function( date, jsEvent, view){
            console.log("event clicked", date.title)
            console.log("event date", date.start._d)
            console.log("jsEvent",jsEvent)
            $scope.alertMessage = (date.title + ' was clicked ');
        };
        /* alert on Drop */
         $scope.alertOnDrop = function(event, delta, revertFunc, jsEvent, ui, view){
            console.log("event delta", view)
            $scope.alertMessage = ('Event Droped to make dayDelta ' + delta);
            console.log("event", event)
        };
        /* alert on Resize */
        $scope.alertOnResize = function(event, delta, revertFunc, jsEvent, ui, view ){
           $scope.alertMessage = ('Event Resized to make dayDelta ' + delta);
        };
        /* add and removes an event source of choice */
        $scope.addRemoveEventSource = function(sources,source) {
          var canAdd = 0;
          angular.forEach(sources,function(value, key){
            if(sources[key] === source){
              sources.splice(key,1);
              canAdd = 1;
            }
          });
          if(canAdd === 0){
            sources.push(source);
          }
        };
        /* add custom event*/
        // $scope.addEvent = function() {
        //   $scope.events.push({
        //     title: 'Open Sesame',
        //     start: new Date(y, m, 28),
        //     end: new Date(y, m, 29),
        //     className: ['openSesame']
        //   });
        // };
        /* remove event */
        $scope.remove = function(index) {
          $scope.events.splice(index,1);
        };
        /* Change View */
        $scope.changeView = function(view,calendar) {
          uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
        };
        /* Change View */
        $scope.renderCalender = function(calendar) {
          if(uiCalendarConfig.calendars[calendar]){
            uiCalendarConfig.calendars[calendar].fullCalendar('render');
          }
        };
         /* Render Tooltip */
        $scope.eventRender = function( event, element, view ) {
            element.attr({'tooltip': event.title,
                         'tooltip-append-to-body': true});
            $compile(element)($scope);
        };
        /* config object */
        $scope.uiConfig = {
          calendar:{
            height: 450,
            editable: true,
            header:{
              left: 'title',
              center: '',
              right: 'today prev,next'
            },
            eventClick: $scope.alertOnEventClick,
            eventDrop: $scope.alertOnDrop,
            eventResize: $scope.alertOnResize,
            eventRender: $scope.eventRender,
          }
        };

        // $scope.changeLang = function() {
        //   if($scope.changeTo === 'Hungarian'){
        //     $scope.uiConfig.calendar.dayNames = ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat"];
        //     $scope.uiConfig.calendar.dayNamesShort = ["Vas", "Hét", "Kedd", "Sze", "Csüt", "Pén", "Szo"];
        //     $scope.changeTo= 'English';
        //   } else {
        //     $scope.uiConfig.calendar.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
        //     $scope.uiConfig.calendar.dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        //     $scope.changeTo = 'Hungarian';
        //   }
        // };
        /* event sources array*/
        $scope.eventSources = [$scope.events, $scope.eventsF];
        // $scope.eventSources2 = [$scope.calEventsExt, $scope.eventsF, $scope.events];

        // Mini popout calendar and text input box
              $scope.today = function() {
                $scope.dt = new Date();
              };
              $scope.today();

              $scope.clear = function() {
                $scope.dt = null;
              };

              $scope.inlineOptions = {
                customClass: getDayClass,
                minDate: new Date(),
                showWeeks: true
              };

              $scope.dateOptions = {
                dateDisabled: disabled,
                formatYear: 'yy',
                maxDate: new Date(2020, 5, 22),
                minDate: new Date(),
                startingDay: 1
              };

              // Disable weekend selection
              function disabled(data) {
                var date = data.date,
                  mode = data.mode;
                return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
                // return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
              }

            //   $scope.toggleMin = function() {
            //     $scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
            //     $scope.dateOptions.minDate = $scope.inlineOptions.minDate;
            //   };
              //
            //   $scope.toggleMin();

              $scope.open1 = function() {
                $scope.popup1.opened = true;

                console.log("this opened")
              };

              $scope.open2 = function() {
                $scope.popup2.opened = true;
              };

            //   $scope.setDate = function(selectedDate) {
            //   $scope.setDate = function(year, month, day) {
                // $scope.dt = new Date(year, month, day);
            //     $scope.dt = selectedDate;
            //     return $scope.dt
            //   };

              $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
              $scope.format = $scope.formats[0];
              $scope.altInputFormats = ['M!/d!/yyyy'];

              $scope.popup1 = {
                opened: false
              };

            //   $scope.popup2 = {
            //     opened: false
            //   };

              var tomorrow = new Date();
              tomorrow.setDate(tomorrow.getDate() + 1);
              var afterTomorrow = new Date();
              afterTomorrow.setDate(tomorrow.getDate() + 1);
            //   $scope.events = [
            //     {
            //       date: tomorrow,
            //       status: 'full'
            //     },
            //     {
            //       date: afterTomorrow,
            //       status: 'partially'
            //     }
            //   ];

              function getDayClass(data) {
                var date = data.date,
                  mode = data.mode;
                // if (mode === 'day') {
                //   var dayToCheck = new Date(date).setHours(0,0,0,0);

                //   for (var i = 0; i < $scope.events.length; i++) {
                    // var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

                    // if (dayToCheck === currentDay) {
                    //   return $scope.events[i].status;
                    // }
                //   }
                // }

                return '';
              }
            // });
    })
<commit_msg>box shows info for selected event<commit_after>Iris
    .controller('CalendarCtrl', function($scope,$http,$timeout,$compile,uiCalendarConfig,irisAPIUrl,RootFactory) {
        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();
        // var tz = date.getTimezoneOffset();
        // console.log("time offset", tz)
        $scope.noteBox = '';
        $scope.events = [];

        RootFactory.getApiRoot()
            .then(
            root => {
                $http.get(`${root.notes}`)
                    .then(res => {
                        console.log("notes res: ", res.data );
                        $scope.populateCalendar(res);
                        $scope.notes= res.data;
                });
                $timeout();
            },
            err => console.log('error', err)
            ).then(
                $timeout //forces scope apply to DOM - reapply everything
            );

        $scope.populateCalendar = function (notes) {
            notes.data.forEach( (note) => {
                $scope.events.push({note_id: note.id, title: note.note_content, start: new Date(note.note_date), allDay: true})
            })
            // console.log($scope.events)
        }

        $scope.addToCalendar = function(noteInfo, selectedDate){
            console.log(selectedDate)
            $http.post(`${irisAPIUrl}/notes/`, {note_content: noteInfo,note_date: selectedDate})
              .then(res => {
                  $scope.events.push({title: res.data.note_content, start: new Date(res.data.note_date), allDay: true})
                console.log("res notes: ", res );
                console.log("events", $scope.events)
                $timeout()
              });
        }

        // $scope.changeTo = 'Hungarian';
        /* event source that pulls from google.com */
        // $scope.eventSource = {
        //         url: "http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
        //         className: 'gcal-event',           // an option!
        //         currentTimezone: 'America/Chicago' // an option!
        // };
        /* event source that contains custom events on the scope */
        // $scope.events = [];
        //   {title: 'All Day Event',start: new Date(y, m, 1)},
        //   {title: 'Long Event',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)},
        //   {id: 999,title: 'Repeating Event',start: new Date(y, m, d - 3, 16, 0),allDay: false},
        //   {id: 999,title: 'Repeating Event',start: new Date(y, m, d + 4, 16, 0),allDay: false},
        //   {title: 'Birthday Party',start: new Date(y, m, d + 1, 19, 0),end: new Date(y, m, d + 1, 22, 30),allDay: false},
        //   {title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}

        /* event source that calls a function on every view switch */
        $scope.eventsF = function (start, end, timezone, callback) {
        //   var s = new Date(start).getTime() / 1000;
        //   var e = new Date(end).getTime() / 1000;
        //   var m = new Date(start).getMonth();
        //   var events = [{title: 'Feed Me ' + m,start: s + (50000),end: s + (100000),allDay: false, className: ['customFeed']}];
          callback($scope.events);
        };

        // $scope.calEventsExt = {
        //    color: '#f00',
        //    textColor: 'yellow',
        //    events: [
        //       {type:'party',title: 'Lunch',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
        //       {type:'party',title: 'Lunch 2',start: new Date(y, m, d, 12, 0),end: new Date(y, m, d, 14, 0),allDay: false},
        //       {type:'party',title: 'Click for Google',start: new Date(y, m, 28),end: new Date(y, m, 29),url: 'http://google.com/'}
        //     ]
        // };
        /* alert on eventClick */
        $scope.alertOnEventClick = function( date, jsEvent, view){
            console.log("event clicked", date.title)
            console.log("event date", date.start._d)
            console.log("event date id", date)
            // console.log("jsEvent",jsEvent)
            $scope.alertMessage = (date.title + ' was clicked ');
            $scope.eventTitle = date.title;
            $scope.eventDate = date.start._d.toLocaleDateString();
        };

        /* alert on Drop */
         $scope.alertOnDrop = function(event, delta, revertFunc, jsEvent, ui, view){
            console.log("event delta", view)
            $scope.alertMessage = ('Event Droped to make dayDelta ' + delta);
            console.log("event", event)
        };
        /* alert on Resize */
        $scope.alertOnResize = function(event, delta, revertFunc, jsEvent, ui, view ){
           $scope.alertMessage = ('Event Resized to make dayDelta ' + delta);
        };
        /* add and removes an event source of choice */
        $scope.addRemoveEventSource = function(sources,source) {
          var canAdd = 0;
          angular.forEach(sources,function(value, key){
            if(sources[key] === source){
              sources.splice(key,1);
              canAdd = 1;
            }
          });
          if(canAdd === 0){
            sources.push(source);
          }
        };
        /* add custom event*/
        // $scope.addEvent = function() {
        //   $scope.events.push({
        //     title: 'Open Sesame',
        //     start: new Date(y, m, 28),
        //     end: new Date(y, m, 29),
        //     className: ['openSesame']
        //   });
        // };
        /* remove event */
        $scope.remove = function(index) {
          $scope.events.splice(index,1);
        };
        /* Change View */
        $scope.changeView = function(view,calendar) {
          uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
        };
        /* Change View */
        $scope.renderCalender = function(calendar) {
          if(uiCalendarConfig.calendars[calendar]){
            uiCalendarConfig.calendars[calendar].fullCalendar('render');
          }
        };
         /* Render Tooltip */
        $scope.eventRender = function( event, element, view ) {
            element.attr({'tooltip': event.title,
                         'tooltip-append-to-body': true});
            $compile(element)($scope);
        };
        /* config object */
        $scope.uiConfig = {
          calendar:{
            height: 450,
            editable: true,
            header:{
              left: 'title',
              center: '',
              right: 'today prev,next'
            },
            eventClick: $scope.alertOnEventClick,
            eventDrop: $scope.alertOnDrop,
            eventResize: $scope.alertOnResize,
            eventRender: $scope.eventRender,
          }
        };

        // $scope.changeLang = function() {
        //   if($scope.changeTo === 'Hungarian'){
        //     $scope.uiConfig.calendar.dayNames = ["Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat"];
        //     $scope.uiConfig.calendar.dayNamesShort = ["Vas", "Hét", "Kedd", "Sze", "Csüt", "Pén", "Szo"];
        //     $scope.changeTo= 'English';
        //   } else {
        //     $scope.uiConfig.calendar.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
        //     $scope.uiConfig.calendar.dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        //     $scope.changeTo = 'Hungarian';
        //   }
        // };
        /* event sources array*/
        $scope.eventSources = [$scope.events, $scope.eventsF];
        // $scope.eventSources2 = [$scope.calEventsExt, $scope.eventsF, $scope.events];

        // Mini popout calendar and text input box
              $scope.today = function() {
                $scope.dt = new Date();
              };
              $scope.today();

              $scope.clear = function() {
                $scope.dt = null;
              };

              $scope.inlineOptions = {
                customClass: getDayClass,
                minDate: new Date(),
                showWeeks: true
              };

              $scope.dateOptions = {
                dateDisabled: disabled,
                formatYear: 'yy',
                maxDate: new Date(2020, 5, 22),
                minDate: new Date(),
                startingDay: 1
              };

              // Disable weekend selection
              function disabled(data) {
                var date = data.date,
                  mode = data.mode;
                return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
                // return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
              }

            //   $scope.toggleMin = function() {
            //     $scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
            //     $scope.dateOptions.minDate = $scope.inlineOptions.minDate;
            //   };
              //
            //   $scope.toggleMin();

              $scope.open1 = function() {
                $scope.popup1.opened = true;

                console.log("this opened")
              };

              $scope.open2 = function() {
                $scope.popup2.opened = true;
              };

            //   $scope.setDate = function(selectedDate) {
            //   $scope.setDate = function(year, month, day) {
                // $scope.dt = new Date(year, month, day);
            //     $scope.dt = selectedDate;
            //     return $scope.dt
            //   };

              $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
              $scope.format = $scope.formats[0];
              $scope.altInputFormats = ['M!/d!/yyyy'];

              $scope.popup1 = {
                opened: false
              };

            //   $scope.popup2 = {
            //     opened: false
            //   };

              var tomorrow = new Date();
              tomorrow.setDate(tomorrow.getDate() + 1);
              var afterTomorrow = new Date();
              afterTomorrow.setDate(tomorrow.getDate() + 1);
            //   $scope.events = [
            //     {
            //       date: tomorrow,
            //       status: 'full'
            //     },
            //     {
            //       date: afterTomorrow,
            //       status: 'partially'
            //     }
            //   ];

              function getDayClass(data) {
                var date = data.date,
                  mode = data.mode;
                // if (mode === 'day') {
                //   var dayToCheck = new Date(date).setHours(0,0,0,0);

                //   for (var i = 0; i < $scope.events.length; i++) {
                    // var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

                    // if (dayToCheck === currentDay) {
                    //   return $scope.events[i].status;
                    // }
                //   }
                // }

                return '';
              }
            // });
    })
<|endoftext|>


<commit_before>/**
 * @author zz85 / http://www.lab4games.net/zz85/blog
 * Defines a 2d shape plane using paths.
 **/

// STEP 1 Create a path.
// STEP 2 Turn path into shape.
// STEP 3 ExtrudeGeometry takes in Shape/Shapes
// STEP 3a - Extract points from each shape, turn to vertices
// STEP 3b - Triangulate each shape, add faces.

THREE.Shape = function ( ) {

	THREE.Path.apply( this, arguments );
	this.holes = [];

};

THREE.Shape.prototype = new THREE.Path();
THREE.Shape.prototype.constructor = THREE.Path;

// Convenience method to return ExtrudeGeometry

THREE.Shape.prototype.extrude = function ( options ) {

	var extruded = new THREE.ExtrudeGeometry( this, options );
	return extruded;

};

// Get points of holes

THREE.Shape.prototype.getPointsHoles = function ( divisions ) {

	var i, il = this.holes.length, holesPts = [];

	for ( i = 0; i < il; i ++ ) {

		holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );

	}

	return holesPts;

};

// Get points of holes (spaced by regular distance)

THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {

	var i, il = this.holes.length, holesPts = [];

	for ( i = 0; i < il; i ++ ) {

		holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );

	}

	return holesPts;

};

// Get points of shape and holes (keypoints based on segments parameter)

THREE.Shape.prototype.extractAllPoints = function ( divisions ) {

	return {

		shape: this.getTransformedPoints( divisions ),
		holes: this.getPointsHoles( divisions )

	};

};

//
// THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
//
// 	return {
//
// 		shape: this.transform( bend, divisions ),
// 		holes: this.getPointsHoles( divisions, bend )
//
// 	};
//
// };

// Get points of shape and holes (spaced by regular distance)

THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {

	return {

		shape: this.getTransformedSpacedPoints( divisions ),
		holes: this.getSpacedPointsHoles( divisions )

	};

};

/**************************************************************
 *	Utils
 **************************************************************/

THREE.Shape.Utils = {

	/*
		contour - array of vector2 for contour
		holes   - array of array of vector2
	*/

	removeHoles: function ( contour, holes ) {

		var shape = contour.concat(); // work on this shape
		var allpoints = shape.concat();

		/* For each isolated shape, find the closest points and break to the hole to allow triangulation */

		var prevShapeVert, nextShapeVert,
			prevHoleVert, nextHoleVert,
			holeIndex, shapeIndex,
			shapeId, shapeGroup,
			h, h2,
			hole, shortest, d,
			p, pts1, pts2,
			tmpShape1, tmpShape2,
			tmpHole1, tmpHole2,
			verts = [];

		for ( h = 0; h < holes.length; h ++ ) {

			hole = holes[ h ];

			/*
			shapeholes[ h ].concat(); // preserves original
			holes.push( hole );
			*/

			allpoints = allpoints.concat( hole );

			shortest = Number.POSITIVE_INFINITY;

			// Find the shortest pair of pts between shape and hole

			// Note: Actually, I'm not sure now if we could optimize this to be faster than O(m*n)
			// Using distanceToSquared() intead of distanceTo() should speed a little
			// since running square roots operations are reduced.

			for ( h2 = 0; h2 < hole.length; h2 ++ ) {

				pts1 = hole[ h2 ];
				var dist = [];

				for ( p = 0; p < shape.length; p++ ) {

					pts2 = shape[ p ];
					d = pts1.distanceToSquared( pts2 );
					dist.push( d );

					if ( d < shortest ) {

						shortest = d;
						holeIndex = h2;
						shapeIndex = p;

					}

				}

			}

			//console.log("shortest", shortest, dist);

			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			var areaapts = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var areaa = THREE.FontUtils.Triangulate.area( areaapts );

			var areabpts = [

				hole[ holeIndex ],
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			var areab = THREE.FontUtils.Triangulate.area( areabpts );

			var shapeOffset = 1;
			var holeOffset = -1;

			var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
			shapeIndex += shapeOffset;
			holeIndex += holeOffset;

			if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
			shapeIndex %= shape.length;

			if ( holeIndex < 0 ) { holeIndex += hole.length;  }
			holeIndex %= hole.length;

			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			areaapts = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );

			areabpts = [

				hole[ holeIndex ],
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
			//console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ),  ( areaa2 + areab2 ));

			if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {

				// In case areas are not correct.
				//console.log("USE THIS");

				shapeIndex = oldShapeIndex;
				holeIndex = oldHoleIndex ;

				if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
				shapeIndex %= shape.length;

				if ( holeIndex < 0 ) { holeIndex += hole.length;  }
				holeIndex %= hole.length;

				prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
				prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			} else {

				//console.log("USE THAT ")

			}

			tmpShape1 = shape.slice( 0, shapeIndex );
			tmpShape2 = shape.slice( shapeIndex );
			tmpHole1 = hole.slice( holeIndex );
			tmpHole2 = hole.slice( 0, holeIndex );

			// Should check orders here again?

			var trianglea = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var triangleb = [

				hole[ holeIndex ] ,
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			verts.push( trianglea );
			verts.push( triangleb );

			shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );

		}

		return {

			shape:shape, 		/* shape with no holes */
			isolatedPts: verts, /* isolated faces */
			allpoints: allpoints

		}

	},

	triangulateShape: function ( contour, holes ) {

		var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );

		var shape = shapeWithoutHoles.shape,
			allpoints = shapeWithoutHoles.allpoints,
			isolatedPts = shapeWithoutHoles.isolatedPts;

		var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape

		// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.

		//console.log( "triangles",triangles, triangles.length );
		//console.log( "allpoints",allpoints, allpoints.length );

		var i, il, f, face,
			key, index,
			allPointsMap = {},
			isolatedPointsMap = {};

		// prepare all points map

		for ( i = 0, il = allpoints.length; i < il; i ++ ) {

			key = allpoints[ i ].x + ":" + allpoints[ i ].y;

			if ( allPointsMap[ key ] !== undefined ) {

				console.log( "Duplicate point", key );

			}

			allPointsMap[ key ] = i;

		}

		// check all face vertices against all points map

		for ( i = 0, il = triangles.length; i < il; i ++ ) {

			face = triangles[ i ];

			for ( f = 0; f < 3; f ++ ) {

				key = face[ f ].x + ":" + face[ f ].y;

				index = allPointsMap[ key ];

				if ( index !== undefined ) {

					face[ f ] = index;

				}

			}

		}

		// check isolated points vertices against all points map

		for ( i = 0, il = isolatedPts.length; i < il; i ++ ) {

			face = isolatedPts[ i ];

			for ( f = 0; f < 3; f ++ ) {

				key = face[ f ].x + ":" + face[ f ].y;

				index = allPointsMap[ key ];

				if ( index !== undefined ) {

					face[ f ] = index;

				}

			}

		}

		return triangles.concat( isolatedPts );

	}, // end triangulate shapes

	/*
	triangulate2 : function( pts, holes ) {

		// For use with Poly2Tri.js

		var allpts = pts.concat();
		var shape = [];
		for (var p in pts) {
			shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
		}

		var swctx = new js.poly2tri.SweepContext(shape);

		for (var h in holes) {
			var aHole = holes[h];
			var newHole = []
			for (i in aHole) {
				newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
				allpts.push(aHole[i]);
			}
			swctx.AddHole(newHole);
		}

		var find;
		var findIndexForPt = function (pt) {
			find = new THREE.Vector2(pt.x, pt.y);
			var p;
			for (p=0, pl = allpts.length; p<pl; p++) {
				if (allpts[p].equals(find)) return p;
			}
			return -1;
		};

		// triangulate
		js.poly2tri.sweep.Triangulate(swctx);

		var triangles =  swctx.GetTriangles();
		var tr ;
		var facesPts = [];
		for (var t in triangles) {
			tr =  triangles[t];
			facesPts.push([
				findIndexForPt(tr.GetPoint(0)),
				findIndexForPt(tr.GetPoint(1)),
				findIndexForPt(tr.GetPoint(2))
					]);
		}

	//	console.log(facesPts);
	//	console.log("triangles", triangles.length, triangles);

		// Returns array of faces with 3 element each
	return facesPts;
	},
*/

	isClockWise: function ( pts ) {

		return THREE.FontUtils.Triangulate.area( pts ) < 0;

	},

	// Bezier Curves formulas obtained from
	// http://en.wikipedia.org/wiki/B%C3%A9zier_curve

	// Quad Bezier Functions

	b2p0: function ( t, p ) {

		var k = 1 - t;
		return k * k * p;

	},

	b2p1: function ( t, p ) {

		return 2 * ( 1 - t ) * t * p;

	},

	b2p2: function ( t, p ) {

		return t * t * p;

	},

	b2: function ( t, p0, p1, p2 ) {

		return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );

	},

	// Cubic Bezier Functions

	b3p0: function ( t, p ) {

		var k = 1 - t;
		return k * k * k * p;

	},

	b3p1: function ( t, p ) {

		var k = 1 - t;
		return 3 * k * k * t * p;

	},

	b3p2: function ( t, p ) {

		var k = 1 - t;
		return 3 * k * t * t * p;

	},

	b3p3: function ( t, p ) {

		return t * t * t * p;

	},

	b3: function ( t, p0, p1, p2, p3 ) {

		return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) +  this.b3p3( t, p3 );

	}

};

<commit_msg>Optimising THREE.Shape.Utils.removeHoles<commit_after>/**
 * @author zz85 / http://www.lab4games.net/zz85/blog
 * Defines a 2d shape plane using paths.
 **/

// STEP 1 Create a path.
// STEP 2 Turn path into shape.
// STEP 3 ExtrudeGeometry takes in Shape/Shapes
// STEP 3a - Extract points from each shape, turn to vertices
// STEP 3b - Triangulate each shape, add faces.

THREE.Shape = function ( ) {

	THREE.Path.apply( this, arguments );
	this.holes = [];

};

THREE.Shape.prototype = new THREE.Path();
THREE.Shape.prototype.constructor = THREE.Path;

// Convenience method to return ExtrudeGeometry

THREE.Shape.prototype.extrude = function ( options ) {

	var extruded = new THREE.ExtrudeGeometry( this, options );
	return extruded;

};

// Get points of holes

THREE.Shape.prototype.getPointsHoles = function ( divisions ) {

	var i, il = this.holes.length, holesPts = [];

	for ( i = 0; i < il; i ++ ) {

		holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );

	}

	return holesPts;

};

// Get points of holes (spaced by regular distance)

THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {

	var i, il = this.holes.length, holesPts = [];

	for ( i = 0; i < il; i ++ ) {

		holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );

	}

	return holesPts;

};

// Get points of shape and holes (keypoints based on segments parameter)

THREE.Shape.prototype.extractAllPoints = function ( divisions ) {

	return {

		shape: this.getTransformedPoints( divisions ),
		holes: this.getPointsHoles( divisions )

	};

};

//
// THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
//
// 	return {
//
// 		shape: this.transform( bend, divisions ),
// 		holes: this.getPointsHoles( divisions, bend )
//
// 	};
//
// };

// Get points of shape and holes (spaced by regular distance)

THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {

	return {

		shape: this.getTransformedSpacedPoints( divisions ),
		holes: this.getSpacedPointsHoles( divisions )

	};

};

/**************************************************************
 *	Utils
 **************************************************************/

THREE.Shape.Utils = {

	/*
		contour - array of vector2 for contour
		holes   - array of array of vector2
	*/

	removeHoles: function ( contour, holes ) {

		var shape = contour.concat(); // work on this shape
		var allpoints = shape.concat();

		/* For each isolated shape, find the closest points and break to the hole to allow triangulation */

		var prevShapeVert, nextShapeVert,
			prevHoleVert, nextHoleVert,
			holeIndex, shapeIndex,
			shapeId, shapeGroup,
			h, h2,
			hole, shortest, d,
			p, pts1, pts2,
			tmpShape1, tmpShape2,
			tmpHole1, tmpHole2,
			verts = [];

		for ( h = 0; h < holes.length; h ++ ) {

			hole = holes[ h ];

			/*
			shapeholes[ h ].concat(); // preserves original
			holes.push( hole );
			*/

			Array.prototype.push.apply( allpoints, hole );

			shortest = Number.POSITIVE_INFINITY;

			// Find the shortest pair of pts between shape and hole

			// Note: Actually, I'm not sure now if we could optimize this to be faster than O(m*n)
			// Using distanceToSquared() intead of distanceTo() should speed a little
			// since running square roots operations are reduced.

			for ( h2 = 0; h2 < hole.length; h2 ++ ) {

				pts1 = hole[ h2 ];
				var dist = [];

				for ( p = 0; p < shape.length; p++ ) {

					pts2 = shape[ p ];
					d = pts1.distanceToSquared( pts2 );
					dist.push( d );

					if ( d < shortest ) {

						shortest = d;
						holeIndex = h2;
						shapeIndex = p;

					}

				}

			}

			//console.log("shortest", shortest, dist);

			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			var areaapts = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var areaa = THREE.FontUtils.Triangulate.area( areaapts );

			var areabpts = [

				hole[ holeIndex ],
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			var areab = THREE.FontUtils.Triangulate.area( areabpts );

			var shapeOffset = 1;
			var holeOffset = -1;

			var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
			shapeIndex += shapeOffset;
			holeIndex += holeOffset;

			if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
			shapeIndex %= shape.length;

			if ( holeIndex < 0 ) { holeIndex += hole.length;  }
			holeIndex %= hole.length;

			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			areaapts = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );

			areabpts = [

				hole[ holeIndex ],
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
			//console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ),  ( areaa2 + areab2 ));

			if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {

				// In case areas are not correct.
				//console.log("USE THIS");

				shapeIndex = oldShapeIndex;
				holeIndex = oldHoleIndex ;

				if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
				shapeIndex %= shape.length;

				if ( holeIndex < 0 ) { holeIndex += hole.length;  }
				holeIndex %= hole.length;

				prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
				prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;

			} else {

				//console.log("USE THAT ")

			}

			tmpShape1 = shape.slice( 0, shapeIndex );
			tmpShape2 = shape.slice( shapeIndex );
			tmpHole1 = hole.slice( holeIndex );
			tmpHole2 = hole.slice( 0, holeIndex );

			// Should check orders here again?

			var trianglea = [

				hole[ holeIndex ],
				shape[ shapeIndex ],
				shape[ prevShapeVert ]

			];

			var triangleb = [

				hole[ holeIndex ] ,
				hole[ prevHoleVert ],
				shape[ shapeIndex ]

			];

			verts.push( trianglea );
			verts.push( triangleb );

			shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );

		}

		return {

			shape:shape, 		/* shape with no holes */
			isolatedPts: verts, /* isolated faces */
			allpoints: allpoints

		}

	},

	triangulateShape: function ( contour, holes ) {

		var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );

		var shape = shapeWithoutHoles.shape,
			allpoints = shapeWithoutHoles.allpoints,
			isolatedPts = shapeWithoutHoles.isolatedPts;

		var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape

		// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.

		//console.log( "triangles",triangles, triangles.length );
		//console.log( "allpoints",allpoints, allpoints.length );

		var i, il, f, face,
			key, index,
			allPointsMap = {},
			isolatedPointsMap = {};

		// prepare all points map

		for ( i = 0, il = allpoints.length; i < il; i ++ ) {

			key = allpoints[ i ].x + ":" + allpoints[ i ].y;

			if ( allPointsMap[ key ] !== undefined ) {

				console.log( "Duplicate point", key );

			}

			allPointsMap[ key ] = i;

		}

		// check all face vertices against all points map

		for ( i = 0, il = triangles.length; i < il; i ++ ) {

			face = triangles[ i ];

			for ( f = 0; f < 3; f ++ ) {

				key = face[ f ].x + ":" + face[ f ].y;

				index = allPointsMap[ key ];

				if ( index !== undefined ) {

					face[ f ] = index;

				}

			}

		}

		// check isolated points vertices against all points map

		for ( i = 0, il = isolatedPts.length; i < il; i ++ ) {

			face = isolatedPts[ i ];

			for ( f = 0; f < 3; f ++ ) {

				key = face[ f ].x + ":" + face[ f ].y;

				index = allPointsMap[ key ];

				if ( index !== undefined ) {

					face[ f ] = index;

				}

			}

		}

		return triangles.concat( isolatedPts );

	}, // end triangulate shapes

	/*
	triangulate2 : function( pts, holes ) {

		// For use with Poly2Tri.js

		var allpts = pts.concat();
		var shape = [];
		for (var p in pts) {
			shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
		}

		var swctx = new js.poly2tri.SweepContext(shape);

		for (var h in holes) {
			var aHole = holes[h];
			var newHole = []
			for (i in aHole) {
				newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
				allpts.push(aHole[i]);
			}
			swctx.AddHole(newHole);
		}

		var find;
		var findIndexForPt = function (pt) {
			find = new THREE.Vector2(pt.x, pt.y);
			var p;
			for (p=0, pl = allpts.length; p<pl; p++) {
				if (allpts[p].equals(find)) return p;
			}
			return -1;
		};

		// triangulate
		js.poly2tri.sweep.Triangulate(swctx);

		var triangles =  swctx.GetTriangles();
		var tr ;
		var facesPts = [];
		for (var t in triangles) {
			tr =  triangles[t];
			facesPts.push([
				findIndexForPt(tr.GetPoint(0)),
				findIndexForPt(tr.GetPoint(1)),
				findIndexForPt(tr.GetPoint(2))
					]);
		}

	//	console.log(facesPts);
	//	console.log("triangles", triangles.length, triangles);

		// Returns array of faces with 3 element each
	return facesPts;
	},
*/

	isClockWise: function ( pts ) {

		return THREE.FontUtils.Triangulate.area( pts ) < 0;

	},

	// Bezier Curves formulas obtained from
	// http://en.wikipedia.org/wiki/B%C3%A9zier_curve

	// Quad Bezier Functions

	b2p0: function ( t, p ) {

		var k = 1 - t;
		return k * k * p;

	},

	b2p1: function ( t, p ) {

		return 2 * ( 1 - t ) * t * p;

	},

	b2p2: function ( t, p ) {

		return t * t * p;

	},

	b2: function ( t, p0, p1, p2 ) {

		return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );

	},

	// Cubic Bezier Functions

	b3p0: function ( t, p ) {

		var k = 1 - t;
		return k * k * k * p;

	},

	b3p1: function ( t, p ) {

		var k = 1 - t;
		return 3 * k * k * t * p;

	},

	b3p2: function ( t, p ) {

		var k = 1 - t;
		return 3 * k * t * t * p;

	},

	b3p3: function ( t, p ) {

		return t * t * t * p;

	},

	b3: function ( t, p0, p1, p2, p3 ) {

		return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) +  this.b3p3( t, p3 );

	}

};

<|endoftext|>


<commit_before>import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import { Table } from 'react-bootstrap/lib';
import './DataView.css';
import DetailView from '../component/DetailView/DetailView';
import {getDataOnStart} from '../actions';
import {connect} from 'react-redux';

import FontAwesome from 'react-fontawesome';
const DataView = ( props ) => {
const {dispatch,serviceData} = props;
var open = false;
var initHeight = 120;
var intval = null;

const filterData =[
    {title:'Microservice 1', description:'Description for Micro Service 1', url:'http://sample1.url'},
    {title:'Microservice 2', description:'Description for Micro Service 2', url:'http://sample2.url'},
    {title:'Microservice 3', description:'Description for Micro Service 3', url:'http://sample3.url'},
    {title:'Microservice 4', description:'Description for Micro Service 4', url:'http://sample4.url'},
    {title:'Microservice 5', description:'Description for Micro Service 5', url:'http://sample5.url'}
  ];

  // let tempData1 =[{title:'Microservice Dummy Data without Server', description:'Description for Micro Service 1', url:'http://sample1.url'}];
  // let Data = serviceData;
  // const filterData = Data;
  // if(null == Data){
  //   Data = tempData1;
  //   fetch("api/catalog")
  //     .then((response)=>{
  //       console.log(response);
  //       if(response.status === 200){
  //         response.json().then((data)=>{
  //           console.log(data);
  //           dispatch(getDataOnStart(data))
  //         })
  //       }
  //     })
  //     .catch( e => console.log(e))
  // }

  const slideToggle = (element) => {
      window.clearInterval(intval);
      var mdiv = document.getElementById('mdiv');
      mdiv = element;
      if(getComputedStyle(mdiv).getPropertyValue('display') === "none"){
        open = false;
      }
      else{
        open = true;
      }
      if(open) {
        mdiv.style.visibility="hidden";
          var h = mdiv.offsetHeight;
          open = false;
          intval = setInterval(function(){
  			h--;
  			mdiv.style.height = h + 'px';
  			if(h <= 0){
  				window.clearInterval(intval);
          mdiv.style.display = 'none';
        }
      }, 1
  		);

      }
      else {
        mdiv.style.display = 'block';
        mdiv.style.visibility = "visible";
          h = 0;
          open = true;
  	    intval = setInterval(function(){
  			h++;
        mdiv.style.height = "auto";
  			if(h >= initHeight)
  				window.clearInterval(intval);
  			}, 1
  		);
      }
  }

const header = [{title:"Title", description:"Description", url:"URL"}];

const head =["Dummy" , "Data"];
const handleArrowClick = (event) => {
  let classes = event.target.classList;
  let classToAdd = 'fa-caret-down';
  if(classes.contains('fa-caret-down')){
    classToAdd = 'fa-caret-up';
  }
  classes.remove('fa-caret-down','fa-caret-up');
  classes.add(classToAdd);
  let element = event.target.closest('tr').nextSibling;
  {slideToggle(element)};
}

let tableData = [];
tableData = filterData.map((dataItem)=>{
      return [

                 {dataItem.title}
                 {dataItem.description}
                 {dataItem.url}
               <FontAwesome className="caret-down" name="caret-down" size="lg" />

,

              <DetailView serviceDetails={head}/>

            ];
          }
        );

return (

        {
          header.map((entry,idx) => (

              {entry.title}
              {entry.description}
              {entry.url}

          )
        )
      }

      {tableData}

);
}

const mapStateToProps = (state) => {
  return{
    serviceData : state.getDataOnLoad.serviceData
  }
}

export default connect(mapStateToProps)(DataView);
<commit_msg>Fetch Data from backend and display #17<commit_after>import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import { Table } from 'react-bootstrap/lib';
import './DataView.css';
import DetailView from '../component/DetailView/DetailView';
import {getDataOnStart} from '../actions';
import {connect} from 'react-redux';

import FontAwesome from 'react-fontawesome';
const DataView = ( props ) => {
  const {dispatch,serviceData} = props;
  var open = false;
  var initHeight = 120;
  var intval = null;

  let filterData = [{title:'Microservice Dummy Data without Server', description:'Description for Micro Service 1', url:'http://sample1.url'}];
  let Data = serviceData;
  if(null == Data){
    Data = filterData;
    fetch("api/catalog")
    .then((response)=>{
      console.log(response);
      if(response.status === 200){
        response.json().then((data)=>{
          console.log(data);
          dispatch(getDataOnStart(data))
        })
      }
    })
    .catch( e => console.log(e))
  }
  else{
    filterData = Data;
  }

  const slideToggle = (element) => {
    window.clearInterval(intval);
    var mdiv = document.getElementById('mdiv');
    mdiv = element;
    if(getComputedStyle(mdiv).getPropertyValue('display') === "none"){
      open = false;
    }
    else{
      open = true;
    }
    if(open) {
      mdiv.style.visibility="hidden";
      var h = mdiv.offsetHeight;
      open = false;
      intval = setInterval(function(){
        h--;
        mdiv.style.height = h + 'px';
        if(h <= 0){
          window.clearInterval(intval);
          mdiv.style.display = 'none';
        }
      }, 1
    );

  }
  else {
    mdiv.style.display = 'block';
    mdiv.style.visibility = "visible";
    h = 0;
    open = true;
    intval = setInterval(function(){
      h++;
      mdiv.style.height = "auto";
      if(h >= initHeight)
      window.clearInterval(intval);
    }, 1
  );
}
}

const header = [{title:"Title", description:"Description", url:"URL"}];

const head =["Dummy" , "Data"];
const handleArrowClick = (event) => {
  let classes = event.target.classList;
  let classToAdd = 'fa-caret-down';
  if(classes.contains('fa-caret-down')){
    classToAdd = 'fa-caret-up';
  }
  classes.remove('fa-caret-down','fa-caret-up');
  classes.add(classToAdd);
  let element = event.target.closest('tr').nextSibling;
  {slideToggle(element)};
}

let tableData = [];
tableData = filterData.map((dataItem)=>{
  return [

       {dataItem.title}
     {dataItem.description}
   {dataItem.url}
 <FontAwesome className="caret-down" name="caret-down" size="lg" />

,

  <DetailView serviceDetails={head}/>

];
}
);

return (

        {
          header.map((entry,idx) => (

              {entry.title}
            {entry.description}
          {entry.url}

  )
)
}

  {tableData}

);
}

const mapStateToProps = (state) => {
  return{
    serviceData : state.getDataOnLoad.serviceData
  }
}

export default connect(mapStateToProps)(DataView);
<|endoftext|>


<commit_before>import Path from 'path';

exports.register = function(server, options, next) {
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: [
          './compiled/',
          Path.join(server.settings.app.repo_root, 'node_modules/nhsuk-frontend/dist/assets/')
        ],
        listing: server.settings.app.debug
      }
    }
  });

  next();
};

exports.register.attributes = {
  name: 'StaticFilesConfig',
  version: '1.0.0',
  dependencies: 'inert'
};
<commit_msg>static files from static directory<commit_after>import Path from 'path';

exports.register = function(server, options, next) {
  server.route({
    method: 'GET',
    path: '/assets/{param*}',
    handler: {
      directory: {
        path: [
          './compiled/',
          Path.join(server.settings.app.repo_root, 'node_modules/nhsuk-frontend/dist/assets/')
        ],
        listing: server.settings.app.debug
      }
    }
  });
  server.route({
    method: 'GET',
    path: '/static/{param*}',
    handler: {
    directory: {
      path: [
        Path.join(server.settings.app.repo_root, 'src/server/static/')
        ],
        listing: server.settings.app.debug
      }
    }
  });
  next();
};

exports.register.attributes = {
  name: 'StaticFilesConfig',
  version: '1.0.0',
  dependencies: 'inert'
};
<|endoftext|>