<commit_before>require('dotenv').config();
var express = require('express');

var fs = require('fs');
var slugify = require('slugify');
// cookies see https://github.com/expressjs/cookie-parser
var cookieParser = require('cookie-parser');
// var cookieSession = require('cookie-session');
var bodyParser = require('body-parser');
var session = require('express-session');
var multer = require('multer');
var util = require('util');
var mime = require('mime');
var compression = require('compression');
var compressible = require('compressible');
var cache = require('apicache').middleware;

var path = require("path");
var temp_dir = path.join(process.cwd(), 'temp/');
var uploads_dir = path.join(process.cwd(), 'uploads/');
// require('ssl-root-cas').inject().addFile('./server.crt');

if (!fs.existsSync(temp_dir)) {
    fs.mkdirSync(temp_dir);
}

if (!fs.existsSync(uploads_dir)) {
    fs.mkdirSync(uploads_dir);
}

var storage = multer.memoryStorage();
var upload = multer({ storage: storage });

//local modules (JS files)
// var utils = require('./utils');
var SentimentAnalysis = require('./lib/sentiment-analysis.js');
var EntityAnalysis = require('./lib/entity-analysis.js');
var LanguageAnalysis = require('./lib/language-analysis.js');
var ImageAnalysis = require('./lib/image-analysis.js');
var NXAPIPacks = require('./lib/api-connector/api-connector.js');

createEJSTemplateDataDictionary = function (req, res) {
  // Set a body class hook to append to <body>
  var localBodyClass = '';
  if(req.originalUrl === '/') {
    localBodyClass = 'home';
  } else {
    localBodyClass = slugify(req.originalUrl.replace(/\//g, ' '));
  }
  return { session: req.session, activeRoute: req.activeRoute, recaptchaSiteKey: process.env.RECAPTCHA_SITE_KEY, bodyClass: localBodyClass };
};

//storage
// var session = require('express-session');
// var RedisStore = require('connect-redis')(session);

var app = express();
// var privateKey  = fs.readFileSync('./key.pem', 'utf8');
// var certificate = fs.readFileSync('./server.crt', 'utf8');
// var credentials = {key: privateKey, cert: certificate};

app.set('port', (process.env.PORT || 5000));

var cookiesSecretKey = (process.env.COOKIES_SECRET_KEY || 'cookiesSecret');

app.use(cookieParser(cookiesSecretKey));

//for now use cookie session (in-memory)
app.use(session({  secret: cookiesSecretKey }));

//
// app.use(session({
//     store: new RedisStore(options),
//     secret: 'secretdata'
// }));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser({limit: '5mb'}));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.use(compression());

//add current route to the request so templates can extract it
app.use(function(req, res, next) {
    req.activeRoute = req.path.split('/')[1] // [0] will be empty since routes start with '/'
    next();
});

app.use(function (req, res, next) {

//don't do this check for the login page, login processing, or the about page
//(about page has two versions, one signed in, one signed out)
  if (req.originalUrl != "/login"
          && req.originalUrl != "/loginCheck"
          && req.originalUrl != "/about") {
    var signedIn = req.cookies.aiKeyCheck;

    if (signedIn !== "ok") {
      // console.log('not signed in');
      req.session.signedIn = undefined
        res.redirect("/login");
        return;
    }
    else {
      req.session.signedIn = "yes"
    }
  }

  next();

});

var markdownCache = Object.create(null);
var SectionPageProcessor = require('./lib/section-page-processor.js');

//docs route - use markdown files as content source for pages
app.get('/docs/*', function(req, res) {

    var dataDict = createEJSTemplateDataDictionary(req, res);

    SectionPageProcessor.processMarkdownPage(dataDict, req, res, markdownCache);

});

app.get('/contact', function(req, res) {
  res.render('pages/contact', createEJSTemplateDataDictionary(req, res));
});

app.get('/login', function(req, res) {
  res.render('pages/login', createEJSTemplateDataDictionary(req, res));
});

app.get('/logout', function (req, res) {
  res.cookie("aiKeyCheck",'');
  req.session.signedIn = undefined
  req.session.loginError = undefined
  res.redirect("/");
});

app.post('/loginCheck', function (req, res) {
  // console.log("phrase = "+req.body.secretKey);
  var secretKey = req.body.secretKey;
  var redirectPath = "/";
  if (secretKey == process.env.A16Z_AI_SECRET_KEY) {
    //set the cookie, redirect to /
    res.cookie("aiKeyCheck",'ok');
  }
  else {
    //redirect to / with an error
    redirectPath = "/login";
    if (secretKey.length > 0) {
      req.session.loginError = "Invalid Key"
    }
  }

  res.redirect(redirectPath);
});

app.get('/', function(req, res) {
  res.render('pages/index', createEJSTemplateDataDictionary(req, res));
});

var apiAddCompletion = function(apiPack, success, message) {
    console.log((success?"OK: ":"ERROR: ")+message);
}

NXAPIPacks.connector.setAPIRoot('/api');
NXAPIPacks.connector.setApp(app);

//on examples, if displayText is not included the value will be used
/*
var entityAnalysisExamples = [
  { "value": "George lives in New York City and his car is a Jaguar XL. George also owns a copy of the Guernica by Picasso. He likes Halloween."},
  { "value": "IBM and Google are companies."},
  { "value": "It is better to commute to San Francisco using BART."}
];
var entityAnalysisServiceInfo
{
  id: "entity-analysis",
  name : "Phrase Entity Analysis",
  description : "Extract entities from sentences or paragraphs.",
  testSamples: entityAnalysisExamples
}
*/

function loadServiceInfo(parameters) {
  var serviceId = parameters.serviceId;
  var loadSamples = parameters.loadSamples;

  var infoPath = path.join(process.cwd(), parameters.topLevelFolder, serviceId, serviceId+"_info.json");
  var info = require(infoPath);
  if ((info != undefined) && loadSamples) {
    var samplesPath = path.join(process.cwd(), parameters.topLevelFolder,  serviceId, serviceId+"_samples.json");
    var samples = require(samplesPath);

    if (samples != undefined) {
      info.testSamples = samples;
    }
  }

  return info;
}

function loadApi(pathToAPIJSONFile) {
  console.log("Loading api info from "+pathToAPIJSONFile);
  var apiInfo = require(pathToAPIJSONFile);
  if (apiInfo != undefined) {
    NXAPIPacks.connector.addAPI(apiInfo);
  }
  else {
    console.log("Error loading API info from "+pathToAPIJSONFile);
  }
}

function loadAllAPIs(rootPath) {
  var folderPath = path.join(process.cwd(), rootPath);

  var files = fs.readdirSync(folderPath);
  files.forEach(file => {
    // console.log(file);

    var filePath = path.join(folderPath, file);
    loadApi(filePath);
  });

}

loadAllAPIs('public/data/services/apis');

var languageAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'language-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var entityAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'entity-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var sentimentAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'sentiment-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var imageAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'image-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

NXAPIPacks.connector
    .apiForId("js-sentimentjs")
        .addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.sentimentJSAPIPack, apiAddCompletion);

NXAPIPacks.connector
    .apiForId("js-sentimental")
        .addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.sentimentalJSAPIPack, apiAddCompletion);

var ibmAPI = NXAPIPacks.connector.apiForId("ibm-alchemy");

ibmAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.alchemyEntityAPIPack, apiAddCompletion);
ibmAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.alchemySentimentAPIPack, apiAddCompletion);
ibmAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.alchemyLangAnalysisAPIPack, apiAddCompletion);

var ibmWatsonAPI = NXAPIPacks.connector.apiForId("ibm-watson");

ibmWatsonAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.ibmToneAnalysisAPIPack, apiAddCompletion);

var googleAPI = NXAPIPacks.connector.apiForId("google-cloud");

googleAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.googleEntityAnalysisAPIPack, apiAddCompletion);
googleAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.googleSentimentAnalysisAPIPack, apiAddCompletion);
googleAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.googleLangAnalysisAPIPack, apiAddCompletion);

googleAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.googleImageAnalysisAPIPack, apiAddCompletion);

var amazonAPI = NXAPIPacks.connector.apiForId("amazon-ai");
amazonAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.amazonImageAnalysisAPIPack, apiAddCompletion);

var clarifaiAPI = NXAPIPacks.connector.apiForId("clarifai");
clarifaiAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.clarifaiImageAnalysisAPIPack, apiAddCompletion);

var msAzureAPI = NXAPIPacks.connector.apiForId("ms-azure");

msAzureAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.msAzureSentimentAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.msAzureEntityAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.msAzureLangAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.msAzureImageAnalysisAPIPack, apiAddCompletion);

var recastAIAPI = NXAPIPacks.connector.apiForId("recast-ai");
recastAIAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.recastaiEntityAPIPack, apiAddCompletion);

var apiAIAPI = NXAPIPacks.connector.apiForId("api-ai");
apiAIAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.apiaiEntityAPIPack, apiAddCompletion);

var image2json = require('./lib/nx/image2json.js');

function registerGet(expressApp, urlPath, serviceId, resultPagePath) {
  //path would end up being something like '/test/phrase/sentiment-analysis',
  const requestPath = path.join(urlPath, serviceId);
  //something like 'pages/data-analysis' to be used in the render() call
  const resultPath = resultPagePath;
  const sid = serviceId;
  const currentApp = expressApp;

//eg  app.get('/test/phrase/sentiment-analysis',
  currentApp.get(requestPath,
      function (req, res) {
        var dataDict =  createEJSTemplateDataDictionary(req, res);

        dataDict.apiServiceInfo = {id: "no_id", name: "No info", description: "no description.", contentType: "none", testSamples: []};
        // dataDict.apis = JSON.stringify();
        var apis = NXAPIPacks.connector.getApisForServiceType(sid); //eg sid = 'sentiment-analysis'

        dataDict.apiEndpoints = [];
        if (apis.length > 0) {
          //get sample text from the first element
          dataDict.apiServiceInfo = apis[0].serviceInfo;
          dataDict.apiContentType = dataDict.apiServiceInfo.contentType;
          if (dataDict.apiServiceInfo.contentType == 'image') {
              dataDict.apiServiceInfo.sampleImages = [];
              for (i in dataDict.apiServiceInfo.testSamples) {
                var imgPath = path.join(process.cwd(), dataDict.apiServiceInfo.testSamples[i].value);
                var jsonInfo = image2json.NXImage.jsonImageFromFile(imgPath);
                dataDict.apiServiceInfo.sampleImages.push(jsonInfo);
              }
          }

          for (i in apis) {
            var api = apis[i];
            var clientPack = api.createClientPack();

            dataDict.apiEndpoints.push(clientPack);
          }
        }

        res.render(resultPath, dataDict);

      });
};

registerGet(app, "/test/phrase", "sentiment-analysis", "pages/data-analysis");
registerGet(app, "/test/phrase", "entity-analysis", "pages/data-analysis");
registerGet(app, "/test/phrase", "language-analysis", "pages/data-analysis");
registerGet(app, "/test/image", "image-analysis", "pages/data-analysis");

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});

//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res){
  res.render('pages/error', createEJSTemplateDataDictionary(req, res));
});
<commit_msg>increased size limit of body parser<commit_after>require('dotenv').config();
var express = require('express');

var fs = require('fs');
var slugify = require('slugify');
// cookies see https://github.com/expressjs/cookie-parser
var cookieParser = require('cookie-parser');
// var cookieSession = require('cookie-session');
var bodyParser = require('body-parser');
var session = require('express-session');
var multer = require('multer');
var util = require('util');
var mime = require('mime');
var compression = require('compression');
var compressible = require('compressible');
var cache = require('apicache').middleware;

var path = require("path");
var temp_dir = path.join(process.cwd(), 'temp/');
var uploads_dir = path.join(process.cwd(), 'uploads/');
// require('ssl-root-cas').inject().addFile('./server.crt');

if (!fs.existsSync(temp_dir)) {
    fs.mkdirSync(temp_dir);
}

if (!fs.existsSync(uploads_dir)) {
    fs.mkdirSync(uploads_dir);
}

var storage = multer.memoryStorage();
var upload = multer({ storage: storage });

//local modules (JS files)
// var utils = require('./utils');
var SentimentAnalysis = require('./lib/sentiment-analysis.js');
var EntityAnalysis = require('./lib/entity-analysis.js');
var LanguageAnalysis = require('./lib/language-analysis.js');
var ImageAnalysis = require('./lib/image-analysis.js');
var NXAPIPacks = require('./lib/api-connector/api-connector.js');

createEJSTemplateDataDictionary = function (req, res) {
  // Set a body class hook to append to <body>
  var localBodyClass = '';
  if(req.originalUrl === '/') {
    localBodyClass = 'home';
  } else {
    localBodyClass = slugify(req.originalUrl.replace(/\//g, ' '));
  }
  return { session: req.session, activeRoute: req.activeRoute, recaptchaSiteKey: process.env.RECAPTCHA_SITE_KEY, bodyClass: localBodyClass };
};

//storage
// var session = require('express-session');
// var RedisStore = require('connect-redis')(session);

var app = express();
// var privateKey  = fs.readFileSync('./key.pem', 'utf8');
// var certificate = fs.readFileSync('./server.crt', 'utf8');
// var credentials = {key: privateKey, cert: certificate};

app.set('port', (process.env.PORT || 5000));

var cookiesSecretKey = (process.env.COOKIES_SECRET_KEY || 'cookiesSecret');

app.use(cookieParser(cookiesSecretKey));

//for now use cookie session (in-memory)
app.use(session({  secret: cookiesSecretKey }));

//
// app.use(session({
//     store: new RedisStore(options),
//     secret: 'secretdata'
// }));

app.use(bodyParser.json({limit: '2mb'}));
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

app.use(express.static(__dirname + '/public'));

// views is directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

app.use(compression());

//add current route to the request so templates can extract it
app.use(function(req, res, next) {
    req.activeRoute = req.path.split('/')[1] // [0] will be empty since routes start with '/'
    next();
});

app.use(function (req, res, next) {

//don't do this check for the login page, login processing, or the about page
//(about page has two versions, one signed in, one signed out)
  if (req.originalUrl != "/login"
          && req.originalUrl != "/loginCheck"
          && req.originalUrl != "/about") {
    var signedIn = req.cookies.aiKeyCheck;

    if (signedIn !== "ok") {
      // console.log('not signed in');
      req.session.signedIn = undefined
        res.redirect("/login");
        return;
    }
    else {
      req.session.signedIn = "yes"
    }
  }

  next();

});

var markdownCache = Object.create(null);
var SectionPageProcessor = require('./lib/section-page-processor.js');

//docs route - use markdown files as content source for pages
app.get('/docs/*', function(req, res) {

    var dataDict = createEJSTemplateDataDictionary(req, res);

    SectionPageProcessor.processMarkdownPage(dataDict, req, res, markdownCache);

});

app.get('/contact', function(req, res) {
  res.render('pages/contact', createEJSTemplateDataDictionary(req, res));
});

app.get('/login', function(req, res) {
  res.render('pages/login', createEJSTemplateDataDictionary(req, res));
});

app.get('/logout', function (req, res) {
  res.cookie("aiKeyCheck",'');
  req.session.signedIn = undefined
  req.session.loginError = undefined
  res.redirect("/");
});

app.post('/loginCheck', function (req, res) {
  // console.log("phrase = "+req.body.secretKey);
  var secretKey = req.body.secretKey;
  var redirectPath = "/";
  if (secretKey == process.env.A16Z_AI_SECRET_KEY) {
    //set the cookie, redirect to /
    res.cookie("aiKeyCheck",'ok');
  }
  else {
    //redirect to / with an error
    redirectPath = "/login";
    if (secretKey.length > 0) {
      req.session.loginError = "Invalid Key"
    }
  }

  res.redirect(redirectPath);
});

app.get('/', function(req, res) {
  res.render('pages/index', createEJSTemplateDataDictionary(req, res));
});

var apiAddCompletion = function(apiPack, success, message) {
    console.log((success?"OK: ":"ERROR: ")+message);
}

NXAPIPacks.connector.setAPIRoot('/api');
NXAPIPacks.connector.setApp(app);

//on examples, if displayText is not included the value will be used
/*
var entityAnalysisExamples = [
  { "value": "George lives in New York City and his car is a Jaguar XL. George also owns a copy of the Guernica by Picasso. He likes Halloween."},
  { "value": "IBM and Google are companies."},
  { "value": "It is better to commute to San Francisco using BART."}
];
var entityAnalysisServiceInfo
{
  id: "entity-analysis",
  name : "Phrase Entity Analysis",
  description : "Extract entities from sentences or paragraphs.",
  testSamples: entityAnalysisExamples
}
*/

function loadServiceInfo(parameters) {
  var serviceId = parameters.serviceId;
  var loadSamples = parameters.loadSamples;

  var infoPath = path.join(process.cwd(), parameters.topLevelFolder, serviceId, serviceId+"_info.json");
  var info = require(infoPath);
  if ((info != undefined) && loadSamples) {
    var samplesPath = path.join(process.cwd(), parameters.topLevelFolder,  serviceId, serviceId+"_samples.json");
    var samples = require(samplesPath);

    if (samples != undefined) {
      info.testSamples = samples;
    }
  }

  return info;
}

function loadApi(pathToAPIJSONFile) {
  console.log("Loading api info from "+pathToAPIJSONFile);
  var apiInfo = require(pathToAPIJSONFile);
  if (apiInfo != undefined) {
    NXAPIPacks.connector.addAPI(apiInfo);
  }
  else {
    console.log("Error loading API info from "+pathToAPIJSONFile);
  }
}

function loadAllAPIs(rootPath) {
  var folderPath = path.join(process.cwd(), rootPath);

  var files = fs.readdirSync(folderPath);
  files.forEach(file => {
    // console.log(file);

    var filePath = path.join(folderPath, file);
    loadApi(filePath);
  });

}

loadAllAPIs('public/data/services/apis');

var languageAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'language-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var entityAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'entity-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var sentimentAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'sentiment-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

var imageAnalysisCommonServiceInfo = loadServiceInfo({serviceId: 'image-analysis', topLevelFolder: 'public/data/services', loadSamples: true});

NXAPIPacks.connector
    .apiForId("js-sentimentjs")
        .addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.sentimentJSAPIPack, apiAddCompletion);

NXAPIPacks.connector
    .apiForId("js-sentimental")
        .addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.sentimentalJSAPIPack, apiAddCompletion);

var ibmAPI = NXAPIPacks.connector.apiForId("ibm-alchemy");

ibmAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.alchemyEntityAPIPack, apiAddCompletion);
ibmAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.alchemySentimentAPIPack, apiAddCompletion);
ibmAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.alchemyLangAnalysisAPIPack, apiAddCompletion);

var ibmWatsonAPI = NXAPIPacks.connector.apiForId("ibm-watson");

ibmWatsonAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.ibmToneAnalysisAPIPack, apiAddCompletion);

var googleAPI = NXAPIPacks.connector.apiForId("google-cloud");

googleAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.googleEntityAnalysisAPIPack, apiAddCompletion);
googleAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.googleSentimentAnalysisAPIPack, apiAddCompletion);
googleAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.googleLangAnalysisAPIPack, apiAddCompletion);

googleAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.googleImageAnalysisAPIPack, apiAddCompletion);

var amazonAPI = NXAPIPacks.connector.apiForId("amazon-ai");
amazonAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.amazonImageAnalysisAPIPack, apiAddCompletion);

var clarifaiAPI = NXAPIPacks.connector.apiForId("clarifai");
clarifaiAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.clarifaiImageAnalysisAPIPack, apiAddCompletion);

var msAzureAPI = NXAPIPacks.connector.apiForId("ms-azure");

msAzureAPI.addService(sentimentAnalysisCommonServiceInfo, SentimentAnalysis.msAzureSentimentAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.msAzureEntityAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(languageAnalysisCommonServiceInfo, LanguageAnalysis.msAzureLangAnalysisAPIPack, apiAddCompletion);
msAzureAPI.addService(imageAnalysisCommonServiceInfo, ImageAnalysis.msAzureImageAnalysisAPIPack, apiAddCompletion);

var recastAIAPI = NXAPIPacks.connector.apiForId("recast-ai");
recastAIAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.recastaiEntityAPIPack, apiAddCompletion);

var apiAIAPI = NXAPIPacks.connector.apiForId("api-ai");
apiAIAPI.addService(entityAnalysisCommonServiceInfo, EntityAnalysis.apiaiEntityAPIPack, apiAddCompletion);

var image2json = require('./lib/nx/image2json.js');

function registerGet(expressApp, urlPath, serviceId, resultPagePath) {
  //path would end up being something like '/test/phrase/sentiment-analysis',
  const requestPath = path.join(urlPath, serviceId);
  //something like 'pages/data-analysis' to be used in the render() call
  const resultPath = resultPagePath;
  const sid = serviceId;
  const currentApp = expressApp;

//eg  app.get('/test/phrase/sentiment-analysis',
  currentApp.get(requestPath,
      function (req, res) {
        var dataDict =  createEJSTemplateDataDictionary(req, res);

        dataDict.apiServiceInfo = {id: "no_id", name: "No info", description: "no description.", contentType: "none", testSamples: []};
        // dataDict.apis = JSON.stringify();
        var apis = NXAPIPacks.connector.getApisForServiceType(sid); //eg sid = 'sentiment-analysis'

        dataDict.apiEndpoints = [];
        if (apis.length > 0) {
          //get sample text from the first element
          dataDict.apiServiceInfo = apis[0].serviceInfo;
          dataDict.apiContentType = dataDict.apiServiceInfo.contentType;
          if (dataDict.apiServiceInfo.contentType == 'image') {
              dataDict.apiServiceInfo.sampleImages = [];
              for (i in dataDict.apiServiceInfo.testSamples) {
                var imgPath = path.join(process.cwd(), dataDict.apiServiceInfo.testSamples[i].value);
                var jsonInfo = image2json.NXImage.jsonImageFromFile(imgPath);
                dataDict.apiServiceInfo.sampleImages.push(jsonInfo);
              }
          }

          for (i in apis) {
            var api = apis[i];
            var clientPack = api.createClientPack();

            dataDict.apiEndpoints.push(clientPack);
          }
        }

        res.render(resultPath, dataDict);

      });
};

registerGet(app, "/test/phrase", "sentiment-analysis", "pages/data-analysis");
registerGet(app, "/test/phrase", "entity-analysis", "pages/data-analysis");
registerGet(app, "/test/phrase", "language-analysis", "pages/data-analysis");
registerGet(app, "/test/image", "image-analysis", "pages/data-analysis");

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});

//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res){
  res.render('pages/error', createEJSTemplateDataDictionary(req, res));
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @class
 */
class Matrix {
    /**
     * @param {array} matrix
     */
    constructor(matrix) {
        if (Array.isArray(matrix) && matrix.every((row, i, m) => {
            return Array.isArray(row) && m[0].length === row.length;
        })) {
            this.matrix = matrix;
            this.width = this.matrix[0].length;
            this.height = this.matrix.length;
        } else {
            throw new Error(`"${matrix}" is not correct matrix.`);
        }
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getRow(number) {
        return this.matrix[number];
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<rows amount>]
     * @returns {array}
     */
    getRows(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.height + begin;

        end = end || this.height;
        end = (end >= 0) ? end : this.height + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getRow(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getColumn(number) {
        let result;

        if (typeof this.matrix[0][number] !== 'undefined') {
            result = this.matrix.map((row) => {
                return row[number];
            });
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<columns amount>]
     * @returns {array}
     */
    getColumns(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.width + begin;

        end = end || this.width;
        end = (end >= 0) ? end : this.width + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getColumn(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getDiagonalMaj(number) {
        let result;
        let diagonalsAmount = this.width + this.height - 1;

        if (number >= 0 && number < diagonalsAmount) {
            result = [];
            let i, j;

            if (number < this.width) {
                // Above major diagonal
                i = this.width - number - 1;
                j = 0;
            } else {
                // Below major diagonal
                i = 0;
                j = number - this.width + 1;
            }

            while (i < this.width && j < this.height) {
                result.push(this.matrix[j][i]);
                i++; j++;
            }
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<parallel diagonals amount>]
     * @returns {array}
     */
    getDiagonalsMaj(begin, end) {
        let result;
        let diagonalsAmount = this.width + this.height - 1;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : diagonalsAmount + begin;

        end = end || diagonalsAmount;
        end = (end >= 0) ? end : diagonalsAmount + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getDiagonalMaj(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getDiagonalMin(number) {
        let result;
        let diagonalsAmount = this.width + this.height - 1;

        if (number >= 0 && number < diagonalsAmount) {
            result = [];
            let i, j;

            if (number < this.width) {
                // Above minor diagonal
                i = number;
                j = 0;
            } else {
                // Below minor diagonal
                i = this.width - 1;
                j = number - this.width + 1;
            }

            while (i >= 0 && j < this.height) {
                result.push(this.matrix[j][i]);
                i--; j++;
            }
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<parallel diagonals amount>]
     * @returns {array}
     */
    getDiagonalsMin(begin, end) {
        let result;
        let diagonalsAmount = this.width + this.height - 1;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : diagonalsAmount + begin;

        end = end || diagonalsAmount;
        end = (end >= 0) ? end : diagonalsAmount + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getDiagonalMin(i));
        }

        return result;
    }
}

module.exports = Matrix;
<commit_msg>oject size of Matrix was added<commit_after>'use strict';

/**
 * @class
 */
class Matrix {
    /**
     * @param {array} matrix
     */
    constructor(matrix) {
        if (Array.isArray(matrix) && matrix.every((row, i, m) => {
            return Array.isArray(row) && m[0].length === row.length;
        })) {
            this.matrix = matrix;

            this.size = {
                width: this.matrix[0].length,
                height: this.matrix.length,
                diagonal: this.matrix[0].length + this.matrix.length - 1
            };
        } else {
            throw new Error(`"${matrix}" is not correct matrix.`);
        }
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getRow(number) {
        return this.matrix[number];
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<rows amount>]
     * @returns {array}
     */
    getRows(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.size.height + begin;

        end = end || this.size.height;
        end = (end >= 0) ? end : this.size.height + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getRow(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getColumn(number) {
        let result;

        if (typeof this.matrix[0][number] !== 'undefined') {
            result = this.matrix.map((row) => {
                return row[number];
            });
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<columns amount>]
     * @returns {array}
     */
    getColumns(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.size.width + begin;

        end = end || this.size.width;
        end = (end >= 0) ? end : this.size.width + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getColumn(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getDiagonalMaj(number) {
        let result;

        if (number >= 0 && number < this.size.diagonal) {
            result = [];
            let i, j;

            if (number < this.size.width) {
                // Above major diagonal
                i = this.size.width - number - 1;
                j = 0;
            } else {
                // Below major diagonal
                i = 0;
                j = number - this.size.width + 1;
            }

            while (i < this.size.width && j < this.size.height) {
                result.push(this.matrix[j][i]);
                i++; j++;
            }
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<parallel diagonals amount>]
     * @returns {array}
     */
    getDiagonalsMaj(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.size.diagonal + begin;

        end = end || this.size.diagonal;
        end = (end >= 0) ? end : this.size.diagonal + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getDiagonalMaj(i));
        }

        return result;
    }

    /**
     * @param {number} number
     * @returns {array}
     */
    getDiagonalMin(number) {
        let result;

        if (number >= 0 && number < this.size.diagonal) {
            result = [];
            let i, j;

            if (number < this.size.width) {
                // Above minor diagonal
                i = number;
                j = 0;
            } else {
                // Below minor diagonal
                i = this.size.width - 1;
                j = number - this.size.width + 1;
            }

            while (i >= 0 && j < this.size.height) {
                result.push(this.matrix[j][i]);
                i--; j++;
            }
        }

        return result;
    }

    /**
     * @param {number} [begin=0]
     * @param {number} [end=<parallel diagonals amount>]
     * @returns {array}
     */
    getDiagonalsMin(begin, end) {
        let result;

        begin = begin || 0;
        begin = (begin >= 0) ? begin : this.size.diagonal + begin;

        end = end || this.size.diagonal;
        end = (end >= 0) ? end : this.size.diagonal + end;

        for (let i = begin; i < end; i++) {
            result = result || [];
            result.push(this.getDiagonalMin(i));
        }

        return result;
    }
}

module.exports = Matrix;
<|endoftext|>


<commit_before>// http://cs.selu.edu/~rbyrd/math/midpoint/
// ((x1+x2)/2), ((y1+y2)/2)
var point = require('turf-point');

module.exports = function(point1, point2) {
  if(point1 === null || point2 === null){
    return new Error('Less than two points passed.');
  }

  var x1 = point1.geometry.coordinates[0];
  var x2 = point2.geometry.coordinates[0];
  var y1 = point1.geometry.coordinates[1];
  var y2 = point2.geometry.coordinates[1];

  var x3 = x1 + x2;
  var midX = x3/2;
  var y3 = y1 + y2;
  var midY = y3/2;

  var midpoint = point(midX, midY);

  return midpoint;
}
<commit_msg>Add jsdoc. Fixes #2<commit_after>// http://cs.selu.edu/~rbyrd/math/midpoint/
// ((x1+x2)/2), ((y1+y2)/2)
var point = require('turf-point');

/**
 * Takes two point features and returns a point between the two.
 *
 * @module turf/midpoint
 * @param {Point} a
 * @param {Point} b
 * @return {Point} a point between the two
 * @example
 * var pt1 = turf.point(0,0)
 * var pt2 = turf.point(10, 0)
 * var midpointed = turf.midpoint(pt1, pt2)
 * var features = turf.featurecollection([
 *  pt1, pt2, midpointed]);
 * //=features
 */
module.exports = function(point1, point2) {
  if(point1 === null || point2 === null){
    return new Error('Less than two points passed.');
  }

  var x1 = point1.geometry.coordinates[0];
  var x2 = point2.geometry.coordinates[0];
  var y1 = point1.geometry.coordinates[1];
  var y2 = point2.geometry.coordinates[1];

  var x3 = x1 + x2;
  var midX = x3/2;
  var y3 = y1 + y2;
  var midY = y3/2;

  var midpoint = point(midX, midY);

  return midpoint;
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {
  View,
  AsyncStorage
} from 'react-native';
import styles from './StyleSheet';
import _ from 'lodash';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import NewTabBar from './replay_scroll_tab_view';
import Content from './content';
import Schedule, {Types} from './ReplayFX_Axios';

//This is a class that has all the info for our swipeable nav bar
export default class Scroll_Tab_View extends Component {

  constructor(props) {
    super(props);
    this.state = {
      //this array gets filled when people start "starring" their schedule
      favorites: [],
      //Array of types of events that will become the names of the tabs
      baseTabs: [
        //hard-coded
        {DisplayName: 'Experience', Name: 'all'},
        {DisplayName: 'My Schedule', Name: 'favorites'}
      ],
      baseSchedule: []
    };

    //binding so we know what 'this' is in reference to the class
    this.addFavorite = this.addFavorite.bind(this);
    this.removeFavorite = this.removeFavorite.bind(this);
    this.loadSchedule = this.loadSchedule.bind(this);
    this.loadFavorites = this.loadFavorites.bind(this);
    this.loadTypes = this.loadTypes.bind(this);
    this.loadLocalSchedule = this.loadLocalSchedule.bind(this);
    this.loadLocalTypes = this.loadLocalTypes.bind(this);

    //callbacks
    setTimeout(this.loadLocalTypes, 1000);
    setTimeout(this.loadTypes, 2000);
    this.loadLocalSchedule();
    this.loadSchedule();
    this.loadFavorites();
  }

  //function that loads favorites from local storage
  loadFavorites() {
    AsyncStorage.getItem('favorites', (err, value) => {
      if (value !== null) {
        this.setState({favorites: JSON.parse(value)});
      }
    });
  }
  //Axios call that gives baseSchedule its state and stores the data
  loadSchedule() {
    Schedule().then((results) => {
      this.setState({baseSchedule: results.data});
      AsyncStorage.setItem('all', JSON.stringify(results.data));
    });
  }
  loadLocalSchedule() {
    AsyncStorage.getItem('all', (err, value) => {
      if (value !== null) {
        this.setState({baseSchedule: JSON.parse(value)});
      }
    });
  }

  //Axios call that receives category types and stores the data
  loadTypes() {
    Types().then((results) => {
      this.setState({tabs: [...this.state.baseTabs, ...results.data]});
      AsyncStorage.setItem('types', JSON.stringify(results.data));
    });
  }

  loadLocalTypes() {
   //AsyncStorage.removeItem('types');
    AsyncStorage.getItem('types', (err, value) => {
      if (value !== null) {
        this.setState({baseTabs: [...this.state.baseTabs, ...JSON.parse(value)]});

      }
    });
  }

  //changes the state of favorites to add a new event id
  addFavorite(id)
  {
    let favorites = [...this.state.favorites, id];
    this.setState({favorites});

    AsyncStorage.setItem('favorites', JSON.stringify(favorites));
  }
  //changes the state of favorite to remove event id
  removeFavorite(id)
{
    let favorites = _.pull(this.state.favorites, id);
    this.setState({favorites});
    AsyncStorage.setItem('favorites', JSON.stringify(favorites));
  }

  render() {

    return (
      // This returns the tabs from the array so we can see them on the screen!
        <ScrollableTabView renderTabBar = {() => <NewTabBar favoritesCount= {this.state.favorites.length}/>} >
          {this.state.baseTabs.map((item, index) =>
          {return (<View style={styles.slide} tabLabel= {item.DisplayName} key = {index} >
            {/* passing the state of the length of the favorites so it's displayed in the
            'my schedule' section on the swipeable nav bar */}
            <Content
              //rendering the state based on whether an item is in the favorites array or not
              typeIs={item.Name}
              favorites={this.state.favorites}
              removeFavorite={this.removeFavorite}
              addFavorite={this.addFavorite}
              baseSchedule={this.state.baseSchedule}/>
          </View>);})}
        </ScrollableTabView>
    );
  }
}
<commit_msg>Working Update<commit_after>import React, {Component} from 'react';
import {
  View,
  AsyncStorage
} from 'react-native';
import styles from './StyleSheet';
import _ from 'lodash';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import NewTabBar from './replay_scroll_tab_view';
import Content from './content';
import Schedule, {Types} from './ReplayFX_Axios';

//This is a class that has all the info for our swipeable nav bar
export default class Scroll_Tab_View extends Component {

  constructor(props) {
    super(props);
    this.state = {
      //this array gets filled when people start "starring" their schedule
      favorites: [],
      //Array of types of events that will become the names of the tabs
      baseTabs: [
        //hard-coded
        {DisplayName: 'Experience', Name: 'all'},
        {DisplayName: 'My Schedule', Name: 'favorites'}
      ],
      baseSchedule: []
    };

    //binding so we know what 'this' is in reference to the class
    this.addFavorite = this.addFavorite.bind(this);
    this.removeFavorite = this.removeFavorite.bind(this);
    this.loadSchedule = this.loadSchedule.bind(this);
    this.loadFavorites = this.loadFavorites.bind(this);
    this.loadTypes = this.loadTypes.bind(this);
    this.loadLocalSchedule = this.loadLocalSchedule.bind(this);
    this.loadLocalTypes = this.loadLocalTypes.bind(this);

    //callbacks
    setTimeout(this.loadLocalTypes, 1500);
    setTimeout(this.loadTypes, 2500);
    this.loadLocalSchedule();
    this.loadSchedule();
    this.loadFavorites();
  }

  //function that loads favorites from local storage
  loadFavorites() {
    AsyncStorage.getItem('favorites', (err, value) => {
      if (value !== null) {
        this.setState({favorites: JSON.parse(value)});
      }
    });
  }
  //Axios call that gives baseSchedule its state and stores the data
  loadSchedule() {
    Schedule().then((results) => {
      this.setState({baseSchedule: results.data});
      AsyncStorage.setItem('all', JSON.stringify(results.data));
    });
  }
  loadLocalSchedule() {
    AsyncStorage.getItem('all', (err, value) => {
      if (value !== null) {
        this.setState({baseSchedule: JSON.parse(value)});
      }
    });
  }

  //Axios call that receives category types and stores the data
  loadTypes() {
    Types().then((results) => {
      this.setState({tabs: [...this.state.baseTabs, ...results.data]});
      AsyncStorage.setItem('types', JSON.stringify(results.data));
    });
  }

  loadLocalTypes() {
   //AsyncStorage.removeItem('types');
    AsyncStorage.getItem('types', (err, value) => {
      if (value !== null) {
        this.setState({baseTabs: [...this.state.baseTabs, ...JSON.parse(value)]});

      }
    });
  }

  //changes the state of favorites to add a new event id
  addFavorite(id)
  {
    let favorites = [...this.state.favorites, id];
    this.setState({favorites});

    AsyncStorage.setItem('favorites', JSON.stringify(favorites));
  }
  //changes the state of favorite to remove event id
  removeFavorite(id)
{
    let favorites = _.pull(this.state.favorites, id);
    this.setState({favorites});
    AsyncStorage.setItem('favorites', JSON.stringify(favorites));
  }

  render() {

    return (
      // This returns the tabs from the array so we can see them on the screen!
        <ScrollableTabView renderTabBar = {() => <NewTabBar favoritesCount= {this.state.favorites.length}/>} >
          {this.state.baseTabs.map((item, index) =>
          {return (<View style={styles.slide} tabLabel= {item.DisplayName} key = {index} >
            {/* passing the state of the length of the favorites so it's displayed in the
            'my schedule' section on the swipeable nav bar */}
            <Content
              //rendering the state based on whether an item is in the favorites array or not
              typeIs={item.Name}
              favorites={this.state.favorites}
              removeFavorite={this.removeFavorite}
              addFavorite={this.addFavorite}
              baseSchedule={this.state.baseSchedule}/>
          </View>);})}
        </ScrollableTabView>
    );
  }
}
<|endoftext|>


<commit_before>var _ = require('lodash');

var standardGeometry = new THREE.PlaneGeometry(1, 1, 1, 1);
function CameraDisplayObject3D(params) {
	params = _.merge({
		width: window.innerWidth,
		height: window.innerHeight,
		resolutionWidth: 100,
		resolutionHeight: 100,
		prescale: 1,
		geometry: standardGeometry,
		renderTargetOptions: undefined,
		generateMipmaps: false
	}, params || {});
	_.assign(this, params);

	//needs a camera
	if(!this.camera) throw new Error("You must provide a camera.");

	//find the scene
	this.scene = this.camera;
	while(this.scene.parent) {
		this.scene = this.scene.parent;
	}
	if(!(this.scene instanceof THREE.Scene)) this.scene = undefined;
	if(!this.scene) throw new Error("Your camera must be a child of a scene.");

	//if its default geometry, width and height should scale
	var scaleToSize = !!this.geometry;

	//material
	if(!this.material) this.material = new THREE.MeshBasicMaterial({
	});

	THREE.Mesh.call(this, this.geometry, this.material);
	this.setResolution(this.resolutionWidth, this.resolutionHeight);
	this.setSize(this.width, this.height);

	//bind the following functions to this because they might be called from other scopes
	var _this = this;
	['render', 'prerender', 'postrender'].forEach(function(funcName) {
		_this[funcName] = _this[funcName].bind(_this);
	});
}

CameraDisplayObject3D.prototype = Object.create(THREE.Mesh.prototype);

_.assign(CameraDisplayObject3D.prototype, {
	prerender: function() {
		// console.log('prerender');
		this.backupAspect = this.camera.aspect;
		this.camera.aspect = this.width / this.height;
		this.camera.updateProjectionMatrix();
	},
	postrender: function() {
		// console.log('postrender');
		this.camera.aspect = this.backupAspect;
		this.camera.updateProjectionMatrix();
	},
	render: function() {
		this.prerender();
		this.renderer.render(this.scene, this.camera, this.renderTarget);
		this.postrender();
	},
	setSize: function(width, height) {
		this.camera;
		this.width = width;
		this.height = height;
		this.scale.x = this.width * this.prescale;
		this.scale.y = this.height * this.prescale;
	},
	setResolution: function(width, height) {
		if(this.renderTarget) this.renderTarget.dispose();
		this.resolutionWidth = width;
		this.resolutionHeight = height;
		this.renderTarget = new THREE.WebGLRenderTarget(this.resolutionWidth, this.resolutionHeight, this.renderTargetOptions);
		this.renderTarget.generateMipmaps = this.generateMipmaps;
		this.material.map = this.renderTarget;
	},
	destroy: function() {
		if(this.parent) this.parent.remove(this);
		this.renderTarget.dispose();
		this.renderer = null;
		this.material.dispose();
		this.material = null;
	}
});
module.exports = CameraDisplayObject3D;<commit_msg>added support for multiple scenes so you can do UI rendering.<commit_after>var _ = require('lodash');

var standardGeometry = new THREE.PlaneGeometry(1, 1, 1, 1);
function CameraDisplayObject3D(params) {
	_.assign(this, _.extend({
		width: window.innerWidth,
		height: window.innerHeight,
		resolutionWidth: 100,
		resolutionHeight: 100,
		prescale: 1,
		geometry: standardGeometry,
		renderTargetOptions: undefined,
		generateMipmaps: false
	}, params));

	//needs a camera
	if(!this.camera) throw new Error("You must provide a camera.");
	if(!this.scene) throw new Error("You must provide a scene or scenes.");

	//find the scene
	if(!this.scene) {
		var scene = this.camera;
		while(scene.parent) {
			scene = scene.parent;
		}
		if(!(scene instanceof THREE.Scene)) this.scene = undefined;
		else this.scene = scene;
		if(!this.scene) throw new Error("Your camera must be a child of a scene.");
	}

	if(this.scene instanceof THREE.Scene) this.render = this.renderOneScene;
	if(this.scene instanceof Array) this.render = this.renderManyScenes;

	//if its default geometry, width and height should scale
	var scaleToSize = !!this.geometry;

	//material
	if(!this.material) this.material = new THREE.MeshBasicMaterial({
	});

	THREE.Mesh.call(this, this.geometry, this.material);
	this.setResolution(this.resolutionWidth, this.resolutionHeight);
	this.setSize(this.width, this.height);

	//bind the following functions to this because they might be called from other scopes
	var _this = this;
	['render', 'prerender', 'postrender'].forEach(function(funcName) {
		_this[funcName] = _this[funcName].bind(_this);
	});
}

CameraDisplayObject3D.prototype = Object.create(THREE.Mesh.prototype);

_.assign(CameraDisplayObject3D.prototype, {
	prerender: function() {
		// console.log('prerender');
		this.backupAspect = this.camera.aspect;
		this.camera.aspect = this.width / this.height;
		this.camera.updateProjectionMatrix();
	},
	postrender: function() {
		// console.log('postrender');
		this.camera.aspect = this.backupAspect;
		this.camera.updateProjectionMatrix();
	},
	renderOneScene: function() {
		this.prerender();
		this.renderer.render(this.scene, this.camera, this.renderTarget);
		this.postrender();
	},
	renderManyScenes: function() {
		this.prerender();
		this.renderer.render(this.scene[0], this.camera, this.renderTarget);
		this.renderer.autoClear = false;
		for (var i = 1; i < this.scene.length; i++) {
			this.renderer.render(this.scene[i], this.camera, this.renderTarget);
		};
		this.renderer.autoClear = true;
		this.postrender();
	},
	setSize: function(width, height) {
		this.camera;
		this.width = width;
		this.height = height;
		this.scale.x = this.width * this.prescale;
		this.scale.y = this.height * this.prescale;
	},
	setResolution: function(width, height) {
		if(this.renderTarget) this.renderTarget.dispose();
		this.resolutionWidth = width;
		this.resolutionHeight = height;
		this.renderTarget = new THREE.WebGLRenderTarget(this.resolutionWidth, this.resolutionHeight, this.renderTargetOptions);
		this.renderTarget.generateMipmaps = this.generateMipmaps;
		this.material.map = this.renderTarget;
	},
	destroy: function() {
		if(this.parent) this.parent.remove(this);
		this.renderTarget.dispose();
		this.renderer = null;
		this.material.dispose();
		this.material = null;
	}
});
module.exports = CameraDisplayObject3D;<|endoftext|>


<commit_before>(function (window, document, undefined, Butter) {

  var urlRegex, videoURL,
    iframe, iframeBody,
    popcornString, butterId,
    userSetMedia, videoString,
    popcornURL, originalHead,
    popcorns;

  Butter.registerModule( "previewer", {

    // setup function used to set default values, as well as setting up the iframe
    setup: function( options ) {

      originalHead = {};
      popcornURL = options.popcornURL || "http://popcornjs.org/code/dist/popcorn-complete.js";
      urlRegex = /(?:http:\/\/www\.|http:\/\/|www\.|\.|^)(youtu|vimeo|soundcloud|baseplayer)/;
      layout = options.layout;
      butterIds = {};
      userSetMedia = options.media;
      popcorns = {};
      videoString = {};

      var that = this,
          targetSrc = document.getElementById( options.target );

        // check if target is a div or iframe
      if ( targetSrc.tagName === "DIV" ) {

        target = document.getElementById( options.target );

        // force iframe to fill parent and set source
        iframe = document.createElement( "IFRAME" );
        iframe.src = layout;
        iframe.width = target.style.width;
        iframe.height = target.style.height;
        target.appendChild( iframe );

        // begin scraping once iframe has loaded, remove listener when complete
        iframe.addEventListener( "load", function (e) {
          that.scraper( iframe, options.callback );
          this.removeEventListener( "load", arguments.callee, false );
        }, false);

      } else if ( targetSrc.tagName === "IFRAME" ) {

        iframe = targetSrc;
        iframe.src = options.layout;

        targetSrc.addEventListener( "load", function (e) {
          that.scraper( iframe, options.callback );
          this.removeEventListener( "load", arguments.callee, false );
        }, false);
      } // else
    }, // setup

    extend: {

      // scraper function that scrapes all DOM elements of the given layout,
      // only scrapes elements with the butter-data attribute
      scraper: function( iframe, callback ) {

        // obtain a reference to the iframes body
        var body = iframe.contentWindow.document.getElementsByTagName( "BODY" ) || iframe.contentDocument.parentWindow.document.getElementsByTagName( "BODY" ),
            that = this;

        Butter.extend( originalHead, iframe.contentWindow.document.head || iframe.contentDocument.parentWindow.document.head );

        //originalHead = iframe.contentWindow.document.head;

        // store original iframeBody incase we rebuild
        var ifrmBody = iframe.contentWindow.document || iframe.contentDocument.parentWindow.document;
        iframeBody = "" + ifrmBody.body.innerHTML + "\n";

        // function to ensure body is actually there
        var ensureLoaded = function() {

          if ( body.length < 1 ) {
            setTimeout( function() {
              ensureLoaded();
            }, 5 );
          } else {

            // begin scraping once body is actually there, call callback once done
            bodyReady( body[ 0 ].children );
            callback();
          } // else
        } // ensureLoaded

        ensureLoaded();

        // scraping is done here
        function bodyReady( children ) {

          // loop for every child of the body
          for( var i = 0; i < children.length; i++ ) {

            // if DOM element has an data-butter tag that is equal to target or media,
            // add it to butters target list with a respective type
            if( children[ i ].getAttribute( "data-butter" ) === "target" ) {
              that.addTarget( {
                name: children[ i ].id,
                type: "target"
              } );
            } else if( children[ i ].getAttribute( "data-butter" ) === "media" ) {
              that.addMedia( {
                name: children[ i ].id,
                media: userSetMedia
              } );
            } // else

            // ensure we get every child, search recursively
            if ( children[ i ].children.length > 0 ) {

              bodyReady( children[ i ].children );
            } // if
          } // for
        } // ok

      }, // scraper

      // buildPopcorn function, builds an instance of popcorn in the iframe and also
      // a local version of popcorn
      buildPopcorn: function( videoTarget, callback ) {

        videoURL = this.getCurrentMedia().getMedia();

        // default to first butter-media tagged object if none is specified
        videoTarget = videoTarget || this.getAllMedia()[ 0 ].getName();

        var bpIframe = iframe.contentWindow.document ||
            iframe.contentDocument.parentWindow.document;
            bpIframe.body.innerHTML = iframeBody;

        // create a string that will create an instance of popcorn with the proper video source
        popcornString = "document.addEventListener('DOMContentLoaded', function () {\n";

        var regexResult = urlRegex.exec( videoURL ) || "",
            players = [], that = this;

        players[ "youtu" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.youtube( '" + videoTarget + "', '" +
            videoURL + "', {\n" +
            "width: 430, height: 300\n" +
          "} ) );\n";
        };

        players[ "vimeo " ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.vimeo( '" + videoTarget + "', '" +
          videoURL + "', {\n" +
            "css: {\n" +
              "width: '430px',\n" +
              "height: '300px'\n" +
            "}\n" +
          "} ) );\n";
        };

        players[ "soundcloud" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.soundcloud( '" + videoTarget + "'," +
          " '" + videoURL + "' ) );\n";
        };

        players[ "baseplayer" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.baseplayer( '" + videoTarget + "' ) );\n";
        };

        players[ undefined ] = function() {
          var src = document.createElement( "source" ),
          video = document.createElement( "video" );
          src.src = videoURL;

          video.style.width = videoTarget.width;
          video.style.height = videoTarget.height;
          video.appendChild( src );
          video.controls = true;
          video.id = videoTarget + "-butter";

          bpIframe.getElementById( videoTarget ).appendChild( video );

          var vidId = "#" + video.id;

          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( '" + vidId + "');\n";
        };

        // call certain player function depending on the regexResult
        players[ regexResult[ 1 ] ]();

        for( video in videoString ) {
          popcornString += videoString[ video ];
        }

        // if for some reason the iframe is refreshed, we want the most up to date popcorn code
        // to be represented in the head of the iframe, incase someone views source
        for( popcorn in popcorns ) {

          var trackEvents = popcorns[ popcorn ].getTrackEvents();

          if ( trackEvents ) {

            // loop through each track event
            for ( var k = 0; k < trackEvents.length; k++ ) {

              // obtain all of the options in the manifest
              var options = trackEvents[ k ]._natives.manifest.options;
              popcornString += " popcorn" + popcorn + "." + trackEvents[ k ]._natives.type + "({\n";

              // for each option
              for ( item in options ) {

                if ( options.hasOwnProperty( item ) ) {

                  // add the data to the string so it looks like normal popcorn code
                  // that someone would write
                  popcornString += item + ": '" + trackEvents[ k ][ item ] + "',\n";
                } // if
              } // for

              popcornString += "});";

            } // for
          } // if
        }

        popcornString += "}, false);";

        this.fillIframe( callback );
      },

      getPopcorn: function( callback ) {
        var popcornz = "var " + videoString;

        // if for some reason the iframe is refreshed, we want the most up to date popcorn code
        // to be represented in the head of the iframe, incase someone views source
        for( popcorn in popcorns ) {

          var trackEvents = popcorns[ popcorn ].getTrackEvents();

          if ( trackEvents ) {

            // loop through each track event
            for ( var k = 0; k < trackEvents.length; k++ ) {

              // obtain all of the options in the manifest
              var options = trackEvents[ k ]._natives.manifest.options;
              popcornz += "popcorn" + popcorn + "." + trackEvents[ k ]._natives.type + "({\n";

              // for each option
              for ( item in options ) {

                if ( options.hasOwnProperty( item ) ) {

                  // add the data to the string so it looks like normal popcorn code
                  // that someone would write
                  popcornz += item + ": '" + trackEvents[ k ][ item ] + "',\n";
                } // if
              } // for

              popcornz += "});\n";

            } // for
          } // if
        }

        return popcornz;

      },

      getRegistry: function() {
        var ifrme = iframe.contentWindow ||
            iframe.contentDocument.parentWindow;
        return ifrme.Popcorn.registry;
      },

      // fillIframe function used to populate the iframe with changes made by the user,
      // which is mostly managing track events added by the user
      fillIframe: function( callback ) {

        var popcornScript, iframeHead, body,
            that = this, doc = iframe.contentWindow.document || iframe.contentDocument.parentWindow.document;

        // create a script within the iframe and populate it with our popcornString
        popcornScript = doc.createElement( "script" );
        popcornScript.innerHTML = popcornString;

        doc.head.appendChild( popcornScript );

        // create a new head element with our new data
        iframeHead = "" + originalHead.innerHTML + "\n\n";

        iframeHead += "\n\n";

        // create a new body element with our new data
        body = doc.body.innerHTML;

        // open, write our changes to the iframe, and close it
        doc.open();
        doc.write( "\n" + iframeHead + body + "\n" );
        doc.close();

        var popcornReady = function( e, callback2 ) {

          var popcornIframe = iframe.contentWindow || iframe.contentDocument.parentWindow;
          var framePopcorn = popcornIframe[ "popcorn" + that.getCurrentMedia().getId() ];

          if ( !framePopcorn ) {
            setTimeout( function() {
              popcornReady( e, callback2 );
            }, 10 );
          } else {
            callback2 && callback2( framePopcorn );
          } // else
        }

        popcornReady( null, function( framePopcorn ) {

          var videoReady = function() {

            if( framePopcorn.media.readyState >= 2 || framePopcorn.media.duration > 0 ) {
              that.duration( framePopcorn.media.duration );

              that.trigger( "mediaready", that.getCurrentMedia() );
              framePopcorn.media.addEventListener( "timeupdate", function() {

                that.currentTime( framePopcorn.media.currentTime );
                that.trigger( "mediatimeupdate", that.getCurrentMedia(), "previewer" );
              },false);
              callback && callback();
            } else {
              setTimeout( function() {
                videoReady( framePopcorn );
              }, 10);
            }
          }
          videoReady( framePopcorn );
        } );

        this.teAdded = function( event ) {
          var that = this, e = event.data;

          popcornReady( e, function( framePopcorn ) {

            var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow

            if( !popcorns[ that.getCurrentMedia().getId() ] ) {
                popcorns[ that.getCurrentMedia().getId() ] = framePopcorn;
            } else {
              framePopcorn = popcorns[ that.getCurrentMedia().getId() ];
            }

            framePopcorn.removeTrackEvent( butterIds[ e.getId() ] );

            // add track events to the iframe verison of popcorn
            framePopcorn[ e.type ]( ifrme.Popcorn.extend( {},
              e.popcornOptions ) );

            butterIds[ e.getId() ] = framePopcorn.getLastTrackEventId();

            e.manifest = framePopcorn.getTrackEvent( butterIds[ e.getId() ] )._natives.manifest;

          } );
        }

        // listen for a trackeventadded
        this.listen( "trackeventupdated", function ( e ) {
          this.teAdded( e );
        }); // listener

        this.listen( "trackeventadded", function ( e ) {
          e = e.data;
          popcornReady( e, function( framePopcorn ) {

            var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow

            if( !popcorns[ that.getCurrentMedia().getId() ] ) {
              popcorns[ that.getCurrentMedia().getId() ] = framePopcorn;
            } else {
              framePopcorn = popcorns[ that.getCurrentMedia().getId() ];
            }

            // add track events to the iframe verison of popcorn
            framePopcorn[ e.type ]( ifrme.Popcorn.extend( {},
              e.popcornOptions ) );

            butterIds[ e.getId() ] = framePopcorn.getLastTrackEventId();

            e.manifest = framePopcorn.getTrackEvent( butterIds[ e.getId() ] )._natives.manifest;
          } );
        }); // listener

        this.listen( "trackeventremoved", function( e ) {
          var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow
          ifrme[ "popcorn" + that.getCurrentMedia().getId() ].removeTrackEvent( butterIds[ e.data.getId() ] );
        } );

        this.listen( "mediachanged", function( e ) {
          that.buildPopcorn( e.data.getName() );
        } );

        this.listen( "mediatimeupdate", function( event ) {

          if ( event.domain === "previewer" ) {
            iframe.contentWindow[ "popcorn" + that.getCurrentMedia().getId() ].currentTime( e.data.currentTime() );
          }
        } );

      } // fillIframe
    } // exnteds

  });
})(window, document, undefined, Butter);
<commit_msg>Fixed some domain issues<commit_after>(function (window, document, undefined, Butter) {

  var urlRegex, videoURL,
    iframe, iframeBody,
    popcornString, butterId,
    userSetMedia, videoString,
    popcornURL, originalHead,
    popcorns;

  Butter.registerModule( "previewer", {

    // setup function used to set default values, as well as setting up the iframe
    setup: function( options ) {

      originalHead = {};
      popcornURL = options.popcornURL || "http://popcornjs.org/code/dist/popcorn-complete.js";
      urlRegex = /(?:http:\/\/www\.|http:\/\/|www\.|\.|^)(youtu|vimeo|soundcloud|baseplayer)/;
      layout = options.layout;
      butterIds = {};
      userSetMedia = options.media;
      popcorns = {};
      videoString = {};

      var that = this,
          targetSrc = document.getElementById( options.target );

        // check if target is a div or iframe
      if ( targetSrc.tagName === "DIV" ) {

        target = document.getElementById( options.target );

        // force iframe to fill parent and set source
        iframe = document.createElement( "IFRAME" );
        iframe.src = layout;
        iframe.width = target.style.width;
        iframe.height = target.style.height;
        target.appendChild( iframe );

        // begin scraping once iframe has loaded, remove listener when complete
        iframe.addEventListener( "load", function (e) {
          that.scraper( iframe, options.callback );
          this.removeEventListener( "load", arguments.callee, false );
        }, false);

      } else if ( targetSrc.tagName === "IFRAME" ) {

        iframe = targetSrc;
        iframe.src = options.layout;

        targetSrc.addEventListener( "load", function (e) {
          that.scraper( iframe, options.callback );
          this.removeEventListener( "load", arguments.callee, false );
        }, false);
      } // else
    }, // setup

    extend: {

      // scraper function that scrapes all DOM elements of the given layout,
      // only scrapes elements with the butter-data attribute
      scraper: function( iframe, callback ) {

        // obtain a reference to the iframes body
        var body = iframe.contentWindow.document.getElementsByTagName( "BODY" ) || iframe.contentDocument.parentWindow.document.getElementsByTagName( "BODY" ),
            that = this;

        Butter.extend( originalHead, iframe.contentWindow.document.head || iframe.contentDocument.parentWindow.document.head );

        //originalHead = iframe.contentWindow.document.head;

        // store original iframeBody incase we rebuild
        var ifrmBody = iframe.contentWindow.document || iframe.contentDocument.parentWindow.document;
        iframeBody = "" + ifrmBody.body.innerHTML + "\n";

        // function to ensure body is actually there
        var ensureLoaded = function() {

          if ( body.length < 1 ) {
            setTimeout( function() {
              ensureLoaded();
            }, 5 );
          } else {

            // begin scraping once body is actually there, call callback once done
            bodyReady( body[ 0 ].children );
            callback();
          } // else
        } // ensureLoaded

        ensureLoaded();

        // scraping is done here
        function bodyReady( children ) {

          // loop for every child of the body
          for( var i = 0; i < children.length; i++ ) {

            // if DOM element has an data-butter tag that is equal to target or media,
            // add it to butters target list with a respective type
            if( children[ i ].getAttribute( "data-butter" ) === "target" ) {
              that.addTarget( {
                name: children[ i ].id,
                type: "target"
              } );
            } else if( children[ i ].getAttribute( "data-butter" ) === "media" ) {
              that.addMedia( {
                name: children[ i ].id,
                media: userSetMedia
              } );
            } // else

            // ensure we get every child, search recursively
            if ( children[ i ].children.length > 0 ) {

              bodyReady( children[ i ].children );
            } // if
          } // for
        } // ok

      }, // scraper

      // buildPopcorn function, builds an instance of popcorn in the iframe and also
      // a local version of popcorn
      buildPopcorn: function( videoTarget, callback ) {

        videoURL = this.getCurrentMedia().getMedia();

        // default to first butter-media tagged object if none is specified
        videoTarget = videoTarget || this.getAllMedia()[ 0 ].getName();

        var bpIframe = iframe.contentWindow.document ||
            iframe.contentDocument.parentWindow.document;
            bpIframe.body.innerHTML = iframeBody;

        // create a string that will create an instance of popcorn with the proper video source
        popcornString = "document.addEventListener('DOMContentLoaded', function () {\n";

        var regexResult = urlRegex.exec( videoURL ) || "",
            players = [], that = this;

        players[ "youtu" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.youtube( '" + videoTarget + "', '" +
            videoURL + "', {\n" +
            "width: 430, height: 300\n" +
          "} ) );\n";
        };

        players[ "vimeo " ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.vimeo( '" + videoTarget + "', '" +
          videoURL + "', {\n" +
            "css: {\n" +
              "width: '430px',\n" +
              "height: '300px'\n" +
            "}\n" +
          "} ) );\n";
        };

        players[ "soundcloud" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.soundcloud( '" + videoTarget + "'," +
          " '" + videoURL + "' ) );\n";
        };

        players[ "baseplayer" ] = function() {
          bpIframe.getElementById( videoTarget ).innerHTML = "";
          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( Popcorn.baseplayer( '" + videoTarget + "' ) );\n";
        };

        players[ undefined ] = function() {
          var src = document.createElement( "source" ),
          video = document.createElement( "video" );
          src.src = videoURL;

          video.style.width = videoTarget.width;
          video.style.height = videoTarget.height;
          video.appendChild( src );
          video.controls = true;
          video.id = videoTarget + "-butter";

          bpIframe.getElementById( videoTarget ).appendChild( video );

          var vidId = "#" + video.id;

          videoString[ that.getCurrentMedia().getId() ] = "popcorn" + that.getCurrentMedia().getId() + " = Popcorn( '" + vidId + "');\n";
        };

        // call certain player function depending on the regexResult
        players[ regexResult[ 1 ] ]();

        for( video in videoString ) {
          popcornString += videoString[ video ];
        }

        // if for some reason the iframe is refreshed, we want the most up to date popcorn code
        // to be represented in the head of the iframe, incase someone views source
        for( popcorn in popcorns ) {

          var trackEvents = popcorns[ popcorn ].getTrackEvents();

          if ( trackEvents ) {

            // loop through each track event
            for ( var k = 0; k < trackEvents.length; k++ ) {

              // obtain all of the options in the manifest
              var options = trackEvents[ k ]._natives.manifest.options;
              popcornString += " popcorn" + popcorn + "." + trackEvents[ k ]._natives.type + "({\n";

              // for each option
              for ( item in options ) {

                if ( options.hasOwnProperty( item ) ) {

                  // add the data to the string so it looks like normal popcorn code
                  // that someone would write
                  popcornString += item + ": '" + trackEvents[ k ][ item ] + "',\n";
                } // if
              } // for

              popcornString += "});";

            } // for
          } // if
        }

        popcornString += "}, false);";

        this.fillIframe( callback );
      },

      getPopcorn: function( callback ) {
        var popcornz = "var " + videoString;

        // if for some reason the iframe is refreshed, we want the most up to date popcorn code
        // to be represented in the head of the iframe, incase someone views source
        for( popcorn in popcorns ) {

          var trackEvents = popcorns[ popcorn ].getTrackEvents();

          if ( trackEvents ) {

            // loop through each track event
            for ( var k = 0; k < trackEvents.length; k++ ) {

              // obtain all of the options in the manifest
              var options = trackEvents[ k ]._natives.manifest.options;
              popcornz += "popcorn" + popcorn + "." + trackEvents[ k ]._natives.type + "({\n";

              // for each option
              for ( item in options ) {

                if ( options.hasOwnProperty( item ) ) {

                  // add the data to the string so it looks like normal popcorn code
                  // that someone would write
                  popcornz += item + ": '" + trackEvents[ k ][ item ] + "',\n";
                } // if
              } // for

              popcornz += "});\n";

            } // for
          } // if
        }

        return popcornz;

      },

      getRegistry: function() {
        var ifrme = iframe.contentWindow ||
            iframe.contentDocument.parentWindow;
        return ifrme.Popcorn.registry;
      },

      // fillIframe function used to populate the iframe with changes made by the user,
      // which is mostly managing track events added by the user
      fillIframe: function( callback ) {

        var popcornScript, iframeHead, body,
            that = this, doc = iframe.contentWindow.document || iframe.contentDocument.parentWindow.document;

        // create a script within the iframe and populate it with our popcornString
        popcornScript = doc.createElement( "script" );
        popcornScript.innerHTML = popcornString;

        doc.head.appendChild( popcornScript );

        // create a new head element with our new data
        iframeHead = "" + originalHead.innerHTML + "\n\n";

        iframeHead += "\n\n";

        // create a new body element with our new data
        body = doc.body.innerHTML;

        // open, write our changes to the iframe, and close it
        doc.open();
        doc.write( "\n" + iframeHead + body + "\n" );
        doc.close();

        var popcornReady = function( e, callback2 ) {

          var popcornIframe = iframe.contentWindow || iframe.contentDocument.parentWindow;
          var framePopcorn = popcornIframe[ "popcorn" + that.getCurrentMedia().getId() ];

          if ( !framePopcorn ) {
            setTimeout( function() {
              popcornReady( e, callback2 );
            }, 10 );
          } else {
            callback2 && callback2( framePopcorn );
          } // else
        }

        popcornReady( null, function( framePopcorn ) {

          var videoReady = function() {

            if( framePopcorn.media.readyState >= 2 || framePopcorn.media.duration > 0 ) {
              that.duration( framePopcorn.media.duration );

              that.trigger( "mediaready", that.getCurrentMedia() );
              framePopcorn.media.addEventListener( "timeupdate", function() {

                that.currentTime( framePopcorn.media.currentTime );
                that.trigger( "mediatimeupdate", that.getCurrentMedia(), "previewer" );
              },false);
              callback && callback();
            } else {
              setTimeout( function() {
                videoReady( framePopcorn );
              }, 10);
            }
          }
          videoReady( framePopcorn );
        } );

        this.teAdded = function( event ) {
          var that = this, e = event.data;

          popcornReady( e, function( framePopcorn ) {

            var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow

            if( !popcorns[ that.getCurrentMedia().getId() ] ) {
                popcorns[ that.getCurrentMedia().getId() ] = framePopcorn;
            } else {
              framePopcorn = popcorns[ that.getCurrentMedia().getId() ];
            }

            framePopcorn.removeTrackEvent( butterIds[ e.getId() ] );

            // add track events to the iframe verison of popcorn
            framePopcorn[ e.type ]( ifrme.Popcorn.extend( {},
              e.popcornOptions ) );

            butterIds[ e.getId() ] = framePopcorn.getLastTrackEventId();

            e.manifest = framePopcorn.getTrackEvent( butterIds[ e.getId() ] )._natives.manifest;

          } );
        }

        // listen for a trackeventadded
        this.listen( "trackeventupdated", function ( e ) {
          this.teAdded( e );
        }); // listener

        this.listen( "trackeventadded", function ( e ) {
          e = e.data;
          popcornReady( e, function( framePopcorn ) {

            var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow

            if( !popcorns[ that.getCurrentMedia().getId() ] ) {
              popcorns[ that.getCurrentMedia().getId() ] = framePopcorn;
            } else {
              framePopcorn = popcorns[ that.getCurrentMedia().getId() ];
            }

            // add track events to the iframe verison of popcorn
            framePopcorn[ e.type ]( ifrme.Popcorn.extend( {},
              e.popcornOptions ) );

            butterIds[ e.getId() ] = framePopcorn.getLastTrackEventId();

            e.manifest = framePopcorn.getTrackEvent( butterIds[ e.getId() ] )._natives.manifest;
          } );
        }); // listener

        this.listen( "trackeventremoved", function( e ) {
          var ifrme = iframe.contentWindow || iframe.contentDocument.parentWindow
          ifrme[ "popcorn" + that.getCurrentMedia().getId() ].removeTrackEvent( butterIds[ e.data.getId() ] );
        } );

        this.listen( "mediachanged", function( e ) {
          that.buildPopcorn( e.data.getName() );
        } );

        this.listen( "mediatimeupdate", function( event ) {

            iframe.contentWindow[ "popcorn" + that.getCurrentMedia().getId() ].currentTim
          }
        }, "timeline" );

      } // fillIframe
    } // exnteds

  });
})(window, document, undefined, Butter);
<|endoftext|>