<commit_before>const models = require("../../../models");
const async = require('async');
const moment = require('moment');
const log = require('../../utils/logger');
const _ = require('lodash');

const TOXICITY_THRESHOLD = 0.50;
const TOXICITY_EMAIL_THRESHOLD = 0.75;

const Perspective = require('perspective-api-client');
let perspectiveApi;
if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
  perspectiveApi = new Perspective({apiKey: process.env.GOOGLE_PERSPECTIVE_API_KEY});
}

const getToxicityScoreForText = (text, doNotStore, callback) => {
  log.info("getToxicityScoreForText starting", { text, doNotStore });
  if (text && text!=="") {
    perspectiveApi.analyze(text, { doNotStore, attributes: [
        'TOXICITY', 'SEVERE_TOXICITY','IDENTITY_ATTACK',
        'THREAT','INSULT','PROFANITY','SEXUALLY_EXPLICIT',
        'FLIRTATION'] }).then( result => {
      log.info("getToxicityScoreForText results", { result });
      callback(null, result);
    }).catch( error => {
      log.error("getToxicityScoreForText error", { error });
      callback(error);
    });
  } else {
    callback("No text for toxicity score");
  }
};

const setupModelPublicDataScore = (model, text, results) => {
  if (!model.data)
    model.set('data', {});
  if (!model.data.moderation)
    model.set('data.moderation', {});
  model.set('data.moderation.rawToxicityResults', results);

  let toxicityScore, severeToxicityScore, identityAttackScore, threatScore, insultScore,
    profanityScore, sexuallyExplicitScore, flirtationScore;

  try {
    toxicityScore = results.attributeScores["TOXICITY"].summaryScore.value;
    severeToxicityScore = results.attributeScores["SEVERE_TOXICITY"].summaryScore.value;
    identityAttackScore = results.attributeScores["IDENTITY_ATTACK"].summaryScore.value;
    threatScore = results.attributeScores["THREAT"].summaryScore.value;
    insultScore = results.attributeScores["INSULT"].summaryScore.value;
    profanityScore = results.attributeScores["PROFANITY"].summaryScore.value;
    sexuallyExplicitScore = results.attributeScores["SEXUALLY_EXPLICIT"].summaryScore.value;
    flirtationScore = results.attributeScores["FLIRTATION"].summaryScore.value;
  } catch (error) {
    log.error(error);
  }

  model.set('data.moderation.toxicityScore', toxicityScore);
  model.set('data.moderation.severeToxicityScore', severeToxicityScore);
  model.set('data.moderation.identityAttackScore', identityAttackScore);
  model.set('data.moderation.threatScore', threatScore);
  model.set('data.moderation.insultScore', insultScore);
  model.set('data.moderation.profanityScore', profanityScore);
  model.set('data.moderation.sexuallyExplicitScore', sexuallyExplicitScore);
  model.set('data.moderation.flirtationScore', flirtationScore);
  model.set('data.moderation.textUsedForScore', text);
};

const hasModelBreachedToxicityThreshold = model => {
  if (model.data && model.data.moderation && (model.data.moderation.toxicityScore || model.data.moderation.severeToxicityScore)) {
    if (model.data.moderation.toxicityScore>TOXICITY_THRESHOLD) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
};

const hasModelBreachedToxicityEmailThreshold = model => {
  if (model.data && model.data.moderation && (model.data.moderation.toxicityScore || model.data.moderation.severeToxicityScore)) {
    if (model.data.moderation.toxicityScore>TOXICITY_EMAIL_THRESHOLD) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
};

const getTranslatedTextForPost = (post, callback) => {
  let postName, postDescription, postTranscript;
  async.parallel([
    (parallelCallback) => {
      const req = { query: {
        textType: 'postName',
        targetLanguage: 'en'
      }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          parallelCallback(error);
        } else {
          postName = translation;
          parallelCallback();
        }
      });
    },
    (parallelCallback) => {
      const req = { query: {
        textType: 'postContent',
        targetLanguage: 'en'
      }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          parallelCallback(error);
        } else {
          postDescription = translation;
          parallelCallback();
        }
      });
    },
    (parallelCallback) => {
      const req = { query: {
          textType: 'postTranscriptContent',
          targetLanguage: 'en'
        }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          log.warn("No text from translate", { error });
          parallelCallback();
        } else {
          postTranscript = translation;
          parallelCallback();
        }
      });
    }
  ], error => {
    if (postName && postDescription) {
      callback(error, `${postName.content} ${postDescription.content} ${postTranscript? postTranscript.content : ''}`);
    } else {
      log.error("No postname for toxicity!", { error });
      callback(error);
    }
  });
};

const getTranslatedTextForPoint = (point, callback) => {
  const req = {
    query: {
      textType: 'pointContent',
      targetLanguage: 'en'
    }
  };
  models.AcTranslationCache.getTranslation(req, point, (error, translation) => {
    if (error) {
      callback(error);
    } else {
      callback(null, translation);
    }
  });
};

const estimateToxicityScoreForPost = (options, callback) => {
  if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
    log.info("getToxicityScoreForText post preparing");
    models.Post.find({
      where: {
        id: options.postId
      },
      include: [
        {
          model: models.Audio,
          as: 'PostAudios',
          required: false
        },
        {
          model: models.Video,
          as: 'PostVideos',
          required: false
        },
        {
          model: models.Group,
          attributes: ['id', 'access'],
          include: [
            {
              model: models.Community,
              required: true,
              attributes: ['id', 'access'],
              include: [
                {
                  model: models.Domain,
                  required: true,
                  attributes: ['id']
                }
              ]
            }
          ]
        },
        {
          model: models.User,
          attribues: ['id','age_group']
        }
      ],
      attributes: ['id','name','description','language','data','group_id','public_data']
    }).then( post => {
      if (post) {
        let doNotStoreValue = post.Group.access===0 && post.Group.Community.access === 0;
        if (post.User.age_group && (post.User.age_group==="0-12" || post.User.age_group==="0"))
          doNotStoreValue = true;

        let textContent, textUsed, transcriptText;

        if (post.public_data &&
            post.public_data.transcript &&
            post.public_data.transcript.text) {
          transcriptText = post.public_data.transcript.text;
        }

        textContent = `${post.name} ${post.description} ${transcriptText? transcriptText : ''}`;

        if (post.language && post.language.substring(0,2)==="en") {
          textUsed = textContent;
          log.info("getToxicityScoreForText post getting english text");
          getToxicityScoreForText(textUsed, doNotStoreValue, callback);
        } else if (textContent && textContent!=='') {
          log.info("getToxicityScoreForText post getting translated text");
          getTranslatedTextForPost(post, (error, translatedText) => {
            log.info("getToxicityScoreForText post got translated text", { translatedText, error });
            if (error)
              callback(error);
            else
              textUsed = translatedText;
              getToxicityScoreForText(textUsed, doNotStoreValue, (error, results) => {
                if (error) {
                  callback(error);
                } else {
                  setupModelPublicDataScore(post, textUsed, results);
                  post.save().then(() => {
                    if (hasModelBreachedToxicityThreshold(post)) {
                      post.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(post) },
                                  "perspectiveAPI",
                                  callback);
                    } else {
                      callback();
                    }
                  }).catch( error => {
                    callback(error);
                  })
                }
              });
          });
        } else {
          log.warn("getToxicityScoreForText post No text for toxicity");
          callback();
        }
      } else {
        log.error("getToxicityScoreForText post could not find post");
        callback("Could not find post");
      }
    }).catch( error => {
      log.error("getToxicityScoreForText post error", { error });
      callback(error);
    })
  } else {
    callback("No API key");
  }
};

const estimateToxicityScoreForPoint = (options, callback) => {
  if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
    log.info("getToxicityScoreForText preparing");
    models.Point.find({
      attributes: ['id','language','data','post_id','group_id'],
      where: {
        id: options.pointId
      },
      include: [
        {
          model: models.Audio,
          as: 'PointAudios',
          required: false
        },
        {
          model: models.Video,
          as: 'PointVideos',
          required: false
        },
        {
          model: models.Group,
          attributes: ['id', 'access'],
          required: false,
          include: [
            {
              model: models.Community,
              required: false,
              attributes: ['id', 'access']
            }
          ]
        },
        {
          model: models.PointRevision,
          attribues: ['id','content']
        },
        {
          model: models.User,
          attribues: ['id','age_group']
        }
      ]
    }).then( point => {
      if (point) {
        let doNotStoreValue = true;
        if (point.Group && point.Group.access===0 && point.Group.Community.access === 0)
          doNotStoreValue = false;

        if (point.User && point.User.age_group && (point.User.age_group==="0-12" || point.User.age_group==="0"))
          doNotStoreValue = true;

        let textContent, textUsed;

        textContent = point.PointRevisions[point.PointRevisions.length-1].content;

        if (point.language && point.language.substring(0,2)==="en") {
          textUsed = textContent;
          log.info("getToxicityScoreForText getting english text");
          getToxicityScoreForText(textContent, doNotStoreValue, callback);
        } else if (textContent && textContent!=='') {
          log.info("getToxicityScoreForText getting translated text");
          getTranslatedTextForPoint(point, (error, translatedText) => {
            log.info("getToxicityScoreForText got translated text", { translatedText, error });
            if (error)
              callback(error);
            else
              textUsed = translatedText.content;
              getToxicityScoreForText(textUsed, doNotStoreValue, (error, results) => {
                if (error) {
                  callback(error);
                } else {
                  setupModelPublicDataScore(point, textUsed, results);
                  point.save().then(() => {
                    if (hasModelBreachedToxicityThreshold(point)) {
                      if (point.post_id) {
                        models.Post.find({
                          where: {
                            id: point.post_id
                          },
                          attributes: ["id",'data'],
                          include: [
                            {
                              model: models.Group,
                              attributes: ['id'],
                              include: [
                                {
                                  model: models.Community,
                                  attributes: ['id'],
                                  include: [
                                    {
                                      model: models.Domain,
                                      attributes: ['id']
                                    }
                                  ]
                                }
                              ]
                            }
                          ]
                        }).then(post => {
                          point.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(point) },
                                       'perspectiveAPI',
                                        post, callback);
                        }).catch( error => {
                          callback(error);
                        });
                      } else {
                        point.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(point) },
                                    'perspectiveAPI', null, callback);
                      }
                    } else {
                      callback();
                    }
                  }).catch( error => {
                    callback(error);
                  })
                }
              });
          });
        } else {
          log.warn("getToxicityScoreForText No text for toxicity");
          callback();
        }
      } else {
        log.error("getToxicityScoreForText could not find point");
        callback("Could not find point");
      }
    }).catch( error => {
      log.error("getToxicityScoreForText error", { error });
      callback(error);
    })
  } else {
    callback("No Google API key");
  }
};

module.exports = {
  estimateToxicityScoreForPoint,
  estimateToxicityScoreForPost
};<commit_msg>Better protection if community is not there<commit_after>const models = require("../../../models");
const async = require('async');
const moment = require('moment');
const log = require('../../utils/logger');
const _ = require('lodash');

const TOXICITY_THRESHOLD = 0.50;
const TOXICITY_EMAIL_THRESHOLD = 0.75;

const Perspective = require('perspective-api-client');
let perspectiveApi;
if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
  perspectiveApi = new Perspective({apiKey: process.env.GOOGLE_PERSPECTIVE_API_KEY});
}

const getToxicityScoreForText = (text, doNotStore, callback) => {
  log.info("getToxicityScoreForText starting", { text, doNotStore });
  if (text && text!=="") {
    perspectiveApi.analyze(text, { doNotStore, attributes: [
        'TOXICITY', 'SEVERE_TOXICITY','IDENTITY_ATTACK',
        'THREAT','INSULT','PROFANITY','SEXUALLY_EXPLICIT',
        'FLIRTATION'] }).then( result => {
      log.info("getToxicityScoreForText results", { result });
      callback(null, result);
    }).catch( error => {
      log.error("getToxicityScoreForText error", { error });
      callback(error);
    });
  } else {
    callback("No text for toxicity score");
  }
};

const setupModelPublicDataScore = (model, text, results) => {
  if (!model.data)
    model.set('data', {});
  if (!model.data.moderation)
    model.set('data.moderation', {});
  model.set('data.moderation.rawToxicityResults', results);

  let toxicityScore, severeToxicityScore, identityAttackScore, threatScore, insultScore,
    profanityScore, sexuallyExplicitScore, flirtationScore;

  try {
    toxicityScore = results.attributeScores["TOXICITY"].summaryScore.value;
    severeToxicityScore = results.attributeScores["SEVERE_TOXICITY"].summaryScore.value;
    identityAttackScore = results.attributeScores["IDENTITY_ATTACK"].summaryScore.value;
    threatScore = results.attributeScores["THREAT"].summaryScore.value;
    insultScore = results.attributeScores["INSULT"].summaryScore.value;
    profanityScore = results.attributeScores["PROFANITY"].summaryScore.value;
    sexuallyExplicitScore = results.attributeScores["SEXUALLY_EXPLICIT"].summaryScore.value;
    flirtationScore = results.attributeScores["FLIRTATION"].summaryScore.value;
  } catch (error) {
    log.error(error);
  }

  model.set('data.moderation.toxicityScore', toxicityScore);
  model.set('data.moderation.severeToxicityScore', severeToxicityScore);
  model.set('data.moderation.identityAttackScore', identityAttackScore);
  model.set('data.moderation.threatScore', threatScore);
  model.set('data.moderation.insultScore', insultScore);
  model.set('data.moderation.profanityScore', profanityScore);
  model.set('data.moderation.sexuallyExplicitScore', sexuallyExplicitScore);
  model.set('data.moderation.flirtationScore', flirtationScore);
  model.set('data.moderation.textUsedForScore', text);
};

const hasModelBreachedToxicityThreshold = model => {
  if (model.data && model.data.moderation && (model.data.moderation.toxicityScore || model.data.moderation.severeToxicityScore)) {
    if (model.data.moderation.toxicityScore>TOXICITY_THRESHOLD) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
};

const hasModelBreachedToxicityEmailThreshold = model => {
  if (model.data && model.data.moderation && (model.data.moderation.toxicityScore || model.data.moderation.severeToxicityScore)) {
    if (model.data.moderation.toxicityScore>TOXICITY_EMAIL_THRESHOLD) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
};

const getTranslatedTextForPost = (post, callback) => {
  let postName, postDescription, postTranscript;
  async.parallel([
    (parallelCallback) => {
      const req = { query: {
        textType: 'postName',
        targetLanguage: 'en'
      }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          parallelCallback(error);
        } else {
          postName = translation;
          parallelCallback();
        }
      });
    },
    (parallelCallback) => {
      const req = { query: {
        textType: 'postContent',
        targetLanguage: 'en'
      }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          parallelCallback(error);
        } else {
          postDescription = translation;
          parallelCallback();
        }
      });
    },
    (parallelCallback) => {
      const req = { query: {
          textType: 'postTranscriptContent',
          targetLanguage: 'en'
        }};
      models.AcTranslationCache.getTranslation(req, post, (error, translation) => {
        if (error) {
          log.warn("No text from translate", { error });
          parallelCallback();
        } else {
          postTranscript = translation;
          parallelCallback();
        }
      });
    }
  ], error => {
    if (postName && postDescription) {
      callback(error, `${postName.content} ${postDescription.content} ${postTranscript? postTranscript.content : ''}`);
    } else {
      log.error("No postname for toxicity!", { error });
      callback(error);
    }
  });
};

const getTranslatedTextForPoint = (point, callback) => {
  const req = {
    query: {
      textType: 'pointContent',
      targetLanguage: 'en'
    }
  };
  models.AcTranslationCache.getTranslation(req, point, (error, translation) => {
    if (error) {
      callback(error);
    } else {
      callback(null, translation);
    }
  });
};

const estimateToxicityScoreForPost = (options, callback) => {
  if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
    log.info("getToxicityScoreForText post preparing");
    models.Post.find({
      where: {
        id: options.postId
      },
      include: [
        {
          model: models.Audio,
          as: 'PostAudios',
          required: false
        },
        {
          model: models.Video,
          as: 'PostVideos',
          required: false
        },
        {
          model: models.Group,
          attributes: ['id', 'access'],
          include: [
            {
              model: models.Community,
              required: true,
              attributes: ['id', 'access'],
              include: [
                {
                  model: models.Domain,
                  required: true,
                  attributes: ['id']
                }
              ]
            }
          ]
        },
        {
          model: models.User,
          attribues: ['id','age_group']
        }
      ],
      attributes: ['id','name','description','language','data','group_id','public_data']
    }).then( post => {
      if (post) {
        let doNotStoreValue = post.Group.access===0 && post.Group.Community.access === 0;
        if (post.User.age_group && (post.User.age_group==="0-12" || post.User.age_group==="0"))
          doNotStoreValue = true;

        let textContent, textUsed, transcriptText;

        if (post.public_data &&
            post.public_data.transcript &&
            post.public_data.transcript.text) {
          transcriptText = post.public_data.transcript.text;
        }

        textContent = `${post.name} ${post.description} ${transcriptText? transcriptText : ''}`;

        if (post.language && post.language.substring(0,2)==="en") {
          textUsed = textContent;
          log.info("getToxicityScoreForText post getting english text");
          getToxicityScoreForText(textUsed, doNotStoreValue, callback);
        } else if (textContent && textContent!=='') {
          log.info("getToxicityScoreForText post getting translated text");
          getTranslatedTextForPost(post, (error, translatedText) => {
            log.info("getToxicityScoreForText post got translated text", { translatedText, error });
            if (error)
              callback(error);
            else
              textUsed = translatedText;
              getToxicityScoreForText(textUsed, doNotStoreValue, (error, results) => {
                if (error) {
                  callback(error);
                } else {
                  setupModelPublicDataScore(post, textUsed, results);
                  post.save().then(() => {
                    if (hasModelBreachedToxicityThreshold(post)) {
                      post.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(post) },
                                  "perspectiveAPI",
                                  callback);
                    } else {
                      callback();
                    }
                  }).catch( error => {
                    callback(error);
                  })
                }
              });
          });
        } else {
          log.warn("getToxicityScoreForText post No text for toxicity");
          callback();
        }
      } else {
        log.error("getToxicityScoreForText post could not find post");
        callback("Could not find post");
      }
    }).catch( error => {
      log.error("getToxicityScoreForText post error", { error });
      callback(error);
    })
  } else {
    callback("No API key");
  }
};

const estimateToxicityScoreForPoint = (options, callback) => {
  if (process.env.GOOGLE_PERSPECTIVE_API_KEY) {
    log.info("getToxicityScoreForText preparing");
    models.Point.find({
      attributes: ['id','language','data','post_id','group_id'],
      where: {
        id: options.pointId
      },
      include: [
        {
          model: models.Audio,
          as: 'PointAudios',
          required: false
        },
        {
          model: models.Video,
          as: 'PointVideos',
          required: false
        },
        {
          model: models.Group,
          attributes: ['id', 'access'],
          required: false,
          include: [
            {
              model: models.Community,
              required: false,
              attributes: ['id', 'access']
            }
          ]
        },
        {
          model: models.PointRevision,
          attribues: ['id','content']
        },
        {
          model: models.User,
          attribues: ['id','age_group']
        }
      ]
    }).then( point => {
      if (point) {
        let doNotStoreValue = true;
        if (point.Group && point.Group.access===0 && (!point.Group.Community || point.Group.Community.access === 0))
          doNotStoreValue = false;

        if (point.User && point.User.age_group && (point.User.age_group==="0-12" || point.User.age_group==="0"))
          doNotStoreValue = true;

        let textContent, textUsed;

        textContent = point.PointRevisions[point.PointRevisions.length-1].content;

        if (point.language && point.language.substring(0,2)==="en") {
          textUsed = textContent;
          log.info("getToxicityScoreForText getting english text");
          getToxicityScoreForText(textContent, doNotStoreValue, callback);
        } else if (textContent && textContent!=='') {
          log.info("getToxicityScoreForText getting translated text");
          getTranslatedTextForPoint(point, (error, translatedText) => {
            log.info("getToxicityScoreForText got translated text", { translatedText, error });
            if (error)
              callback(error);
            else
              textUsed = translatedText.content;
              getToxicityScoreForText(textUsed, doNotStoreValue, (error, results) => {
                if (error) {
                  callback(error);
                } else {
                  setupModelPublicDataScore(point, textUsed, results);
                  point.save().then(() => {
                    if (hasModelBreachedToxicityThreshold(point)) {
                      if (point.post_id) {
                        models.Post.find({
                          where: {
                            id: point.post_id
                          },
                          attributes: ["id",'data'],
                          include: [
                            {
                              model: models.Group,
                              attributes: ['id'],
                              include: [
                                {
                                  model: models.Community,
                                  attributes: ['id'],
                                  include: [
                                    {
                                      model: models.Domain,
                                      attributes: ['id']
                                    }
                                  ]
                                }
                              ]
                            }
                          ]
                        }).then(post => {
                          point.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(point) },
                                       'perspectiveAPI',
                                        post, callback);
                        }).catch( error => {
                          callback(error);
                        });
                      } else {
                        point.report({ disableNotification: !hasModelBreachedToxicityEmailThreshold(point) },
                                    'perspectiveAPI', null, callback);
                      }
                    } else {
                      callback();
                    }
                  }).catch( error => {
                    callback(error);
                  })
                }
              });
          });
        } else {
          log.warn("getToxicityScoreForText No text for toxicity");
          callback();
        }
      } else {
        log.error("getToxicityScoreForText could not find point");
        callback("Could not find point");
      }
    }).catch( error => {
      log.error("getToxicityScoreForText error", { error });
      callback(error);
    })
  } else {
    callback("No Google API key");
  }
};

module.exports = {
  estimateToxicityScoreForPoint,
  estimateToxicityScoreForPost
};<|endoftext|>


<commit_before>import 'react-app-polyfill/ie11';
import React, { Fragment } from 'react';
import { render } from 'react-dom';
import config from 'react-global-configuration';
import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { reducer as formReducer } from 'redux-form';
import { Provider as TranslationProvider } from 'retranslate';
import { Provider as ReduxProvider } from 'react-redux';
import { Router, Route, browserHistory } from 'react-router';
import {
  routerReducer as routingReducer,
  routerMiddleware,
  syncHistoryWithStore,
} from 'react-router-redux';
import mixpanel from 'mixpanel-browser';
import MixpanelProvider from 'react-mixpanel';
import GoogleAnalytics from 'react-ga';

import { getQueryParams } from './utils';
import { initializeConfiguration, updateLanguage } from './components/config/config';
import translations from './components/translations';
import './components/index.scss';

import requireAuthentication from './components/requireAuthentication';
import LoginPage, { reducer as loginReducer, actions as loginActions } from './components/login';
import TermsOfUse from './components/termsOfUse';
import NonMember from './components/newUserFlow/nonMember';
import { reducer as exchangeReducer, actions as exchangeActions } from './components/exchange';
import {
  reducer as thirdPillarReducer,
  actions as thirdPillarActions,
} from './components/thirdPillar';
import trackingReducer from './components/tracking';
import { actions as routerActions } from './components/router';

import './common/polyfills';
import LoggedInApp from './components/LoggedInApp';
import AccountPage, {
  reducer as accountReducer,
  actions as accountActions,
} from './components/account';
import {
  actions as returnComparisonActions,
  reducer as returnComparisonReducer,
} from './components/returnComparison';
import SecondPillarFlow, {
  SelectSources,
  TransferFutureCapital,
  ConfirmMandate,
  Success,
} from './components/flows/secondPillar';
import { unregister as unregisterServiceWorker } from './common/registerServiceWorker';

const rootReducer = combineReducers({
  routing: routingReducer,
  login: loginReducer,
  exchange: exchangeReducer, // exchage of funds
  account: accountReducer,
  returnComparison: returnComparisonReducer,
  thirdPillar: thirdPillarReducer,
  tracking: trackingReducer,
  form: formReducer,
});

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // eslint-disable-line

const routingMiddleware = routerMiddleware(browserHistory);

const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk, routingMiddleware)));

const history = syncHistoryWithStore(browserHistory, store);

function getSourceAndTargetFundsData() {
  const { login, exchange } = store.getState();
  if (
    login.token &&
    !(
      exchange.sourceFunds ||
      exchange.loadingSourceFunds ||
      exchange.targetFunds ||
      exchange.loadingTargetFunds
    )
  ) {
    store.dispatch(exchangeActions.getSourceFunds());
    store.dispatch(exchangeActions.getTargetFunds());
  }
}

async function getUserAndConversionData() {
  const { login } = store.getState();

  if (login.userConversionError || login.userError) {
    store.dispatch(loginActions.logOut());
  } else if (
    login.token &&
    (!(login.user || login.loadingUser) || !(login.userConversion || login.loadingUserConversion))
  ) {
    await Promise.all([
      store.dispatch(loginActions.getUserConversion()),
      store.dispatch(loginActions.getUser()),
    ]);
    await getSourceAndTargetFundsData();
    await store.dispatch(routerActions.selectRouteForState());
  }
  return Promise.resolve();
}

function applyRouting() {
  const queryParams = getQueryParams();
  store.dispatch(loginActions.handleIdCardLogin(queryParams));
  store.dispatch(thirdPillarActions.addDataFromQueryParams(queryParams));
}

function getDataForApp() {
  applyRouting();
  return getUserAndConversionData();
}

async function initApp(nextState, replace, callback) {
  await getDataForApp();
  callback();
}

function getInitialCapitalData() {
  const { login, account } = store.getState();
  if (
    login.token &&
    login.user &&
    login.user.memberNumber &&
    !(account.initialCapital || account.loadingInitialCapital)
  ) {
    store.dispatch(accountActions.getInitialCapital());
  }
}

function getPendingExchangesData() {
  const { login, exchange } = store.getState();
  if (login.token && !(exchange.pendingExchanges || exchange.loadingPendingExchanges)) {
    store.dispatch(exchangeActions.getPendingExchanges());
  }
}

function getReturnComparisonData() {
  const {
    login,
    returnComparison: { loading, actualPercentage },
  } = store.getState();
  if (login.token && !(actualPercentage !== null || loading)) {
    store.dispatch(returnComparisonActions.getReturnComparisonForStartDate(null));
  }
}

function getDataForAccount() {
  getSourceAndTargetFundsData();
  getInitialCapitalData();
  getPendingExchangesData();
  getReturnComparisonData();
}

function applyLanguage() {
  const params = window.location.search;

  let language = 'et';
  if (params.indexOf('language=et') >= 0) {
    language = 'et';
  } else if (params.indexOf('language=en') >= 0) {
    language = 'en';
  }
  updateLanguage(language);

  return language;
}

function scrollToTop() {
  window.scrollTo(0, 0);
}

initializeConfiguration();

window.config = config; // for debug only

mixpanel.init(config.get('mixpanelKey'));

GoogleAnalytics.initialize('UA-76855836-1', {
  debug: false,
  titleCase: false,
  gaOptions: {
    alwaysSendReferrer: true,
  },
});

function trackPageView() {
  if (process.env.NODE_ENV === 'production') {
    GoogleAnalytics.pageview(window.location.href);
  }
}

const secondPillarFlowSteps = [
  { path: 'select-sources', component: SelectSources },
  { path: 'transfer-future-capital', component: TransferFutureCapital },
  { path: 'confirm-mandate', component: ConfirmMandate },
];

const App = () => (
  <MixpanelProvider mixpanel={mixpanel}>
    <TranslationProvider messages={translations} language={applyLanguage()} fallbackLanguage="et">
      <ReduxProvider store={store}>
        <Router onUpdate={trackPageView} history={history}>
          <Fragment>
            <Route path="/login" component={LoginPage} />
            <Route path="/terms-of-use" component={TermsOfUse} />
            <Route path="/" component={requireAuthentication(LoggedInApp)} onEnter={initApp}>
              <Route path="/2nd-pillar-flow">
                <Route path="non-member" component={NonMember} />
              </Route>

              <Route path="2nd-pillar-flow" component={SecondPillarFlow}>
                {secondPillarFlowSteps.map(({ path, component }) => (
                  <Route path={path} component={component} onEnter={scrollToTop} />
                ))}
              </Route>
              <Route path="/2nd-pillar-flow/success" component={Success} />
              <Route path="/account" component={AccountPage} onEnter={getDataForAccount} />
            </Route>
          </Fragment>
        </Router>
      </ReduxProvider>
    </TranslationProvider>
  </MixpanelProvider>
);

render(<App />, document.getElementById('root'));

unregisterServiceWorker();
<commit_msg>Make onboarding App a class component, apply routing after mount<commit_after>import 'react-app-polyfill/ie11';
import React, { Component, Fragment } from 'react';
import { render } from 'react-dom';
import config from 'react-global-configuration';
import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { reducer as formReducer } from 'redux-form';
import { Provider as TranslationProvider } from 'retranslate';
import { Provider as ReduxProvider } from 'react-redux';
import { Router, Route, browserHistory } from 'react-router';
import {
  routerReducer as routingReducer,
  routerMiddleware,
  syncHistoryWithStore,
} from 'react-router-redux';
import mixpanel from 'mixpanel-browser';
import MixpanelProvider from 'react-mixpanel';
import GoogleAnalytics from 'react-ga';

import { getQueryParams } from './utils';
import { initializeConfiguration, updateLanguage } from './components/config/config';
import translations from './components/translations';
import './components/index.scss';

import requireAuthentication from './components/requireAuthentication';
import LoginPage, { reducer as loginReducer, actions as loginActions } from './components/login';
import TermsOfUse from './components/termsOfUse';
import NonMember from './components/newUserFlow/nonMember';
import { reducer as exchangeReducer, actions as exchangeActions } from './components/exchange';
import {
  reducer as thirdPillarReducer,
  actions as thirdPillarActions,
} from './components/thirdPillar';
import trackingReducer from './components/tracking';
import { actions as routerActions } from './components/router';

import './common/polyfills';
import LoggedInApp from './components/LoggedInApp';
import AccountPage, {
  reducer as accountReducer,
  actions as accountActions,
} from './components/account';
import {
  actions as returnComparisonActions,
  reducer as returnComparisonReducer,
} from './components/returnComparison';
import SecondPillarFlow, {
  SelectSources,
  TransferFutureCapital,
  ConfirmMandate,
  Success,
} from './components/flows/secondPillar';
import { unregister as unregisterServiceWorker } from './common/registerServiceWorker';

const rootReducer = combineReducers({
  routing: routingReducer,
  login: loginReducer,
  exchange: exchangeReducer, // exchage of funds
  account: accountReducer,
  returnComparison: returnComparisonReducer,
  thirdPillar: thirdPillarReducer,
  tracking: trackingReducer,
  form: formReducer,
});

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; // eslint-disable-line

const routingMiddleware = routerMiddleware(browserHistory);

const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk, routingMiddleware)));

const history = syncHistoryWithStore(browserHistory, store);

function getSourceAndTargetFundsData() {
  const { login, exchange } = store.getState();
  if (
    login.token &&
    !(
      exchange.sourceFunds ||
      exchange.loadingSourceFunds ||
      exchange.targetFunds ||
      exchange.loadingTargetFunds
    )
  ) {
    store.dispatch(exchangeActions.getSourceFunds());
    store.dispatch(exchangeActions.getTargetFunds());
  }
}

async function getUserAndConversionData() {
  const { login } = store.getState();

  if (login.userConversionError || login.userError) {
    store.dispatch(loginActions.logOut());
  } else if (
    login.token &&
    (!(login.user || login.loadingUser) || !(login.userConversion || login.loadingUserConversion))
  ) {
    await Promise.all([
      store.dispatch(loginActions.getUserConversion()),
      store.dispatch(loginActions.getUser()),
    ]);
    await getSourceAndTargetFundsData();
    await store.dispatch(routerActions.selectRouteForState());
  }
  return Promise.resolve();
}

function applyRouting() {
  const queryParams = getQueryParams();
  store.dispatch(loginActions.handleIdCardLogin(queryParams));
  store.dispatch(thirdPillarActions.addDataFromQueryParams(queryParams));
}

function getDataForApp() {
  return getUserAndConversionData();
}

async function initApp(nextState, replace, callback) {
  await getDataForApp();
  callback();
}

function getInitialCapitalData() {
  const { login, account } = store.getState();
  if (
    login.token &&
    login.user &&
    login.user.memberNumber &&
    !(account.initialCapital || account.loadingInitialCapital)
  ) {
    store.dispatch(accountActions.getInitialCapital());
  }
}

function getPendingExchangesData() {
  const { login, exchange } = store.getState();
  if (login.token && !(exchange.pendingExchanges || exchange.loadingPendingExchanges)) {
    store.dispatch(exchangeActions.getPendingExchanges());
  }
}

function getReturnComparisonData() {
  const {
    login,
    returnComparison: { loading, actualPercentage },
  } = store.getState();
  if (login.token && !(actualPercentage !== null || loading)) {
    store.dispatch(returnComparisonActions.getReturnComparisonForStartDate(null));
  }
}

function getDataForAccount() {
  getSourceAndTargetFundsData();
  getInitialCapitalData();
  getPendingExchangesData();
  getReturnComparisonData();
}

function applyLanguage() {
  const params = window.location.search;

  let language = 'et';
  if (params.indexOf('language=et') >= 0) {
    language = 'et';
  } else if (params.indexOf('language=en') >= 0) {
    language = 'en';
  }
  updateLanguage(language);

  return language;
}

function scrollToTop() {
  window.scrollTo(0, 0);
}

initializeConfiguration();

window.config = config; // for debug only

mixpanel.init(config.get('mixpanelKey'));

GoogleAnalytics.initialize('UA-76855836-1', {
  debug: false,
  titleCase: false,
  gaOptions: {
    alwaysSendReferrer: true,
  },
});

function trackPageView() {
  if (process.env.NODE_ENV === 'production') {
    GoogleAnalytics.pageview(window.location.href);
  }
}

const secondPillarFlowSteps = [
  { path: 'select-sources', component: SelectSources },
  { path: 'transfer-future-capital', component: TransferFutureCapital },
  { path: 'confirm-mandate', component: ConfirmMandate },
];

class App extends Component {
  componentDidMount() {
    applyRouting();
  }

  render() {
    return (
      <MixpanelProvider mixpanel={mixpanel}>
        <TranslationProvider
          messages={translations}
          language={applyLanguage()}
          fallbackLanguage="et"
        >
          <ReduxProvider store={store}>
            <Router onUpdate={trackPageView} history={history}>
              <Fragment>
                <Route path="/login" component={LoginPage} />
                <Route path="/terms-of-use" component={TermsOfUse} />
                <Route path="/" component={requireAuthentication(LoggedInApp)} onEnter={initApp}>
                  <Route path="/2nd-pillar-flow">
                    <Route path="non-member" component={NonMember} />
                  </Route>

                  <Route path="2nd-pillar-flow" component={SecondPillarFlow}>
                    {secondPillarFlowSteps.map(({ path, component }) => (
                      <Route path={path} component={component} onEnter={scrollToTop} />
                    ))}
                  </Route>
                  <Route path="/2nd-pillar-flow/success" component={Success} />
                  <Route path="/account" component={AccountPage} onEnter={getDataForAccount} />
                </Route>
              </Fragment>
            </Router>
          </ReduxProvider>
        </TranslationProvider>
      </MixpanelProvider>
    );
  }
}

render(<App />, document.getElementById('root'));

unregisterServiceWorker();
<|endoftext|>


<commit_before>'use strict';

var cellsPositions = [],
	order = 0,
	canvas;

function createGrid() {

	order = document.getElementsByName('order')[0].value;
	if(!!order && order > 0) {
		cellsPositions = [];
		drawCanvas(order);
	} else {
		alert("Please type valid order");
	}
}

function drawCanvas() {
	var elem = document.getElementById('environment'),
  	distance = order * 33.75;
  	canvas = elem.getContext('2d');

	elem.width = Math.round(distance) + 15;
	elem.height = Math.round(distance) + 15;
	elem.addEventListener('click', changeCellStatus);

  	canvas.fillStyle = "#ccc";

	//(x, y, distance_x, distance_y)
	canvas.clearRect(10, 10, distance, distance);
  	canvas.strokeRect(10, 10, distance, distance);

  	drawCells(canvas);
}

function changeCellStatus(event) {
	var x = event.offsetX,
		y = event.offsetY;

	for(let index = 0, len = cellsPositions.length; index <= len ; index++) {
		let cell = cellsPositions[index],
			right = cell.x + cell.size,
			left = cell.x,
			top = cell.y,
			bottom = cell.y + cell.size,
			isSelected = right >= x && left <= x && bottom >= y && top <= y;

		if(isSelected) {
			cell.isAlive = !cell.isAlive;
			changeCellCanvas(cell);
			return;
		}
	}
}

function changeCellCanvas(cell){
	canvas.fillStyle = cell.isAlive ? '#0f0' : '#ccc';
	canvas.fillRect(cell.x, cell.y, cell.size, cell.size);
}

function drawCells(canvas) {
	var size = 30,
		y = 15,
		cellsQuantity = order;

	for(; cellsQuantity>0; cellsQuantity --) {
		let cells = order,
			x = 15;
		for(; cells>0; cells --) {
			cellsPositions.push({x: x, y: y, size: size, isAlive: false});
			canvas.fillRect(x, y, size, size);
			x += 31;
		}
		y += 31;
	}
	document.getElementById('next-button').className = '';
}

function createNewGeneration() {

	var cellStates = [],
		cells = [],
		environment = new Environment(order),
		newGeneration = [];

	cellStates = cellsPositions.map(function(cell) {
		return new Cell(cell.isAlive);
	});

	while(cellStates.length) {
	    cells.push(cellStates.splice(0, order));
	}
	environment.setCells(cells);

	newGeneration = environment.nextGeneration();
	// flatten array
	newGeneration = [].concat.apply([], newGeneration);

	cellsPositions.forEach(function(cell, index) {
		cell.isAlive = newGeneration[index].isAlive;
		changeCellCanvas(cell);
	});
}<commit_msg>Code refactor, names changed, specific functions created<commit_after>'use strict';

var cellsPositions = [],
	gridSize = 0,
	canvas;

function createGrid() {

	gridSize = document.getElementById('grid-size').value;
	if(!!gridSize && gridSize > 0) {
		cellsPositions = [];
		drawCanvas();
	} else {
		alert("Please type valid gridSize");
	}
}

function drawCanvas() {
	var elem = document.getElementById('environment'),
	  	gridHeightWidth = gridSize * 33.75,
	  	elemHeightWidth = Math.round(gridHeightWidth) + 15;

	elem.width = elemHeightWidth;
	elem.height = elemHeightWidth;
	elem.addEventListener('click', changeCellStatus);

 	canvas = elem.getContext('2d');
  	canvas.fillStyle = "#ccc";
	canvas.clearRect(10, 10, gridHeightWidth, gridHeightWidth);

  	drawCells();
}

function changeCellStatus(event) {
	var x = event.offsetX,
		y = event.offsetY;

	cellsPositions.forEach(function (cell) {
		let right = cell.x + cell.cellSize,
			left = cell.x,
			top = cell.y,
			bottom = cell.y + cell.cellSize,
			isSelected = right >= x && left <= x && bottom >= y && top <= y;

		if(isSelected) {
			cell.isAlive = !cell.isAlive;
			changeCellCanvas(cell);
			return;
		}
	});
}

function changeCellCanvas(cell){
	canvas.fillStyle = cell.isAlive ? '#0f0' : '#ccc';
	canvas.fillRect(cell.x, cell.y, cell.cellSize, cell.cellSize);
}

function drawCells() {
	var cellSize = 30,
		y = 15,
		cellsQuantity = gridSize;

	for(; cellsQuantity>0; cellsQuantity --) {
		let cells = gridSize,
			x = 15;
		for(; cells>0; cells --) {
			cellsPositions.push({x: x, y: y, cellSize: cellSize, isAlive: false});
			canvas.fillRect(x, y, cellSize, cellSize);
			x += 31;
		}
		y += 31;
	}
	document.getElementById('next-gen-btn').className = '';
}

function createNewGeneration() {

	var environment = new Environment(gridSize),
		newGeneration = [];

	environment.setCells(getCellsArray());
	newGeneration = environment.nextGeneration();
	// flatten array
	newGeneration = [].concat.apply([], newGeneration);
	//changing cell color according to new status
	cellsPositions.forEach(function(cell, index) {
		cell.isAlive = newGeneration[index].isAlive;
		changeCellCanvas(cell);
	});
}

function getCellsArray() {
	var cells = [],
		cellStates = [];
	//Get cell's status of life in a plain array
	cellStates = cellsPositions.map(function(cell) {
		return new Cell(cell.isAlive);
	});
	//Making a two-dimensional array
	while(cellStates.length) {
	    cells.push(cellStates.splice(0, gridSize));
	}
	return cells;
}<|endoftext|>


<commit_before>// https://github.com/kriskowal/q/issues/303

var Q = require("q");

function promiseLog(message) {
    return Q.fcall(function() {
        console.write(message);
    });
}

promiseLog("a")
.then(promiseLog("b"))
.then(function() {
    return promiseLog("c")
    .then(promiseLog("d"));
})
.then(promiseLog("e"));<commit_msg>ugh, not sure why I left .write() in there<commit_after>// https://github.com/kriskowal/q/issues/303

var Q = require("q");

function promiseLog(message) {
    return Q.fcall(function() {
        console.log(message);
    });
}

promiseLog("a")
.then(promiseLog("b"))
.then(function() {
    return promiseLog("c")
    .then(promiseLog("d"));
})
.then(promiseLog("e"));<|endoftext|>


<commit_before>(function() {
  'use strict';

  define(['jquery', 'text!config.json'], function($, config_text) {

    var get_query_variable = function(name) {
      name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
      var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
          results = regex.exec(location.search);
      return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    };

    var config_file = JSON.parse(config_text);

    var config = {
      debug: config_file['debug'],
      logLevel: config_file['logLevel'],
      base_url: config_file['base_url'],
      exp_id: get_query_variable('exp_id'),
      app_id: get_query_variable('app_id'),
      origin: get_query_variable('origin'),
      // data options move to post messaging
      flavor: get_query_variable('flavor'),
      multiselect: JSON.parse(get_query_variable('multiselect')),
      link: JSON.parse(get_query_variable('link')),
      direct_link: JSON.parse(get_query_variable('direct_link')),
      computer: JSON.parse(get_query_variable('computer')),
      account_key: JSON.parse(get_query_variable('account_key')),
      services: JSON.parse(get_query_variable('services')),
      persist: JSON.parse(get_query_variable('persist')),
      types: JSON.parse(get_query_variable('types')).map(function(str) {
        /**
         * Make sure all types are lowercase since we do a case-insensitive
         * search by lowercasing the search key and using types#indexOf.
         */
        return str.toLowerCase();
      }),
      user_data: {}, // Get asynchronously.
      copy_to_upload_location: JSON.parse(get_query_variable('copy_to_upload_location')),
      create_folder: JSON.parse(get_query_variable('create_folder')),
      chunk_size: 5*1024*1024,
    };

    // Get user_data
    var query_params = {app_id: config.app_id}
    if (config.account_key) {
      // Only do origin check if we need to.
      query_params['origin'] = config.origin
    }
    $.get(config.base_url + "/file-explorer/config/", query_params,
          function(config_data) {
            config.user_data = (config_data && config_data.user_data) || {};

            if (config.onReceiveUserData) {
              config.onReceiveUserData(config.user_data);
            }
          });

    if (config.types.indexOf('folders') != -1 && config.types.length === 1) {
        config.computer = false;
    }

    // Service aliases
    var services = {
        all: [
            'dropbox',
            'gdrive',
            'box',
            'evernote',
            'skydrive',
            'sugarsync',
            'sharefile',
            'copy',
            'egnyte',
            's3',
            'sharepoint',
            'onedrivebiz',
            'azure',
            'cmis',
            'alfresco'
        ],
        file_store: [
            'dropbox',
            'gdrive',
            'box',
            'evernote',
            'skydrive',
            'sugarsync',
            'sharefile',
            'copy',
            'egnyte',
            'sharepoint',
            'onedrivebiz',
            'cmis',
            'alfresco'
        ],
        object_store: [
            'azure',
            's3']
    };

    var groups = [];
    if (config.services == undefined) {
        config.services = [];
        config.services = config.services.concat(services.file_store);
    } else if (config.services.length == 0) {
        config.services = [];
    } else {
        config.services = config.services.filter(function(service) {
          if (service in services) {
            groups = groups.concat(services[service]);
            return false;
          }
          return true;
        }).concat(groups);
    }

    // Type aliases.
    var aliases = {
      all: [
        'all'
      ],
      text: [
        'applescript',
        'as',
        'as3',
        'c',
        'cc',
        'clisp',
        'coffee',
        'cpp',
        'cs',
        'css',
        'csv',
        'cxx',
        'def',
        'diff',
        'erl',
        'fountain',
        'ft',
        'h',
        'hpp',
        'htm',
        'html',
        'hxx',
        'inc',
        'ini',
        'java',
        'js',
        'json',
        'less',
        'log',
        'lua',
        'm',
        'markdown',
        'mat',
        'md',
        'mdown',
        'mkdn',
        'mm',
        'mustache',
        'mxml',
        'patch',
        'php',
        'phtml',
        'pl',
        'plist',
        'properties',
        'py',
        'rb',
        'sass',
        'scss',
        'sh',
        'shtml',
        'sql',
        'tab',
        'taskpaper',
        'tex',
        'text',
        'tmpl',
        'tsv',
        'txt',
        'url',
        'vb',
        'xhtml',
        'xml',
        'yaml',
        'yml',
        ''],
      documents: [
        'csv',
        'doc',
        'dochtml',
        'docm',
        'docx',
        'docxml',
        'dot',
        'dothtml',
        'dotm',
        'dotx',
        'eps',
        'fdf',
        'key',
        'keynote',
        'kth',
        'mpd',
        'mpp',
        'mpt',
        'mpx',
        'nmbtemplate',
        'numbers',
        'odc',
        'odg',
        'odp',
        'ods',
        'odt',
        'pages',
        'pdf',
        'pdfxml',
        'pot',
        'pothtml',
        'potm',
        'potx',
        'ppa',
        'ppam',
        'pps',
        'ppsm',
        'ppsx',
        'ppt',
        'ppthtml',
        'pptm',
        'pptx',
        'pptxml',
        'prn',
        'ps',
        'pwz',
        'rtf',
        'tab',
        'template',
        'tsv',
        'txt',
        'vdx',
        'vsd',
        'vss',
        'vst',
        'vsx',
        'vtx',
        'wbk',
        'wiz',
        'wpd',
        'wps',
        'xdf',
        'xdp',
        'xlam',
        'xll',
        'xlr',
        'xls',
        'xlsb',
        'xlsm',
        'xlsx',
        'xltm',
        'xltx',
        'xps'],
      images: [
        'bmp',
        'cr2',
        'gif',
        'ico',
        'ithmb',
        'jpeg',
        'jpg',
        'nef',
        'png',
        'raw',
        'svg',
        'tif',
        'tiff',
        'wbmp',
        'webp'],
      videos: [
        '3g2',
        '3gp',
        '3gpp',
        '3gpp2',
        'asf',
        'avi',
        'dv',
        'dvi',
        'flv',
        'm2t',
        'm4v',
        'mkv',
        'mov',
        'mp4',
        'mpeg',
        'mpg',
        'mts',
        'ogv',
        'ogx',
        'rm',
        'rmvb',
        'ts',
        'vob',
        'webm',
        'wmv'],
      audio: [
        'aac',
        'aif',
        'aifc',
        'aiff',
        'au',
        'flac',
        'm4a',
        'm4b',
        'm4p',
        'm4r',
        'mid',
        'mp3',
        'oga',
        'ogg',
        'opus',
        'ra',
        'ram',
        'spx',
        'wav',
        'wma'],
      ebooks: [
        'acsm',
        'aeh',
        'azw',
        'cb7',
        'cba',
        'cbr',
        'cbt',
        'cbz',
        'ceb',
        'chm',
        'epub',
        'fb2',
        'ibooks',
        'kf8',
        'lit',
        'lrf',
        'lrx',
        'mobi',
        'opf',
        'oxps',
        'pdf',
        'pdg',
        'prc',
        'tebr',
        'tr2',
        'tr3',
        'xeb',
        'xps']
      }
      , additions = [];

    config.types = config.types.filter(function(type) {
      if (type in aliases) {
        additions = additions.concat(aliases[type]);
        return false;
      }
      return true;
    }).concat(additions);

    // remove any duplicates
    config.types = config.types.filter(function(elem, pos) {
        return config.types.indexOf(elem) == pos;
    });

    // default to 'all'
    if (config.types.length === 0) {
        config.types.push('all');
    }

    if (config.debug) {
        window.config = config;
    }

    return config;
  });
})();
<commit_msg>Adding additional services to config.<commit_after>(function() {
  'use strict';

  define(['jquery', 'text!config.json'], function($, config_text) {

    var get_query_variable = function(name) {
      name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
      var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
          results = regex.exec(location.search);
      return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    };

    var config_file = JSON.parse(config_text);

    var config = {
      debug: config_file['debug'],
      logLevel: config_file['logLevel'],
      base_url: config_file['base_url'],
      exp_id: get_query_variable('exp_id'),
      app_id: get_query_variable('app_id'),
      origin: get_query_variable('origin'),
      // data options move to post messaging
      flavor: get_query_variable('flavor'),
      multiselect: JSON.parse(get_query_variable('multiselect')),
      link: JSON.parse(get_query_variable('link')),
      direct_link: JSON.parse(get_query_variable('direct_link')),
      computer: JSON.parse(get_query_variable('computer')),
      account_key: JSON.parse(get_query_variable('account_key')),
      services: JSON.parse(get_query_variable('services')),
      persist: JSON.parse(get_query_variable('persist')),
      types: JSON.parse(get_query_variable('types')).map(function(str) {
        /**
         * Make sure all types are lowercase since we do a case-insensitive
         * search by lowercasing the search key and using types#indexOf.
         */
        return str.toLowerCase();
      }),
      user_data: {}, // Get asynchronously.
      copy_to_upload_location: JSON.parse(get_query_variable('copy_to_upload_location')),
      create_folder: JSON.parse(get_query_variable('create_folder')),
      chunk_size: 5*1024*1024,
    };

    // Get user_data
    var query_params = {app_id: config.app_id}
    if (config.account_key) {
      // Only do origin check if we need to.
      query_params['origin'] = config.origin
    }
    $.get(config.base_url + "/file-explorer/config/", query_params,
          function(config_data) {
            config.user_data = (config_data && config_data.user_data) || {};

            if (config.onReceiveUserData) {
              config.onReceiveUserData(config.user_data);
            }
          });

    if (config.types.indexOf('folders') != -1 && config.types.length === 1) {
        config.computer = false;
    }

    // Service aliases
    var services = {
        all: [
            'dropbox',
            'gdrive',
            'box',
            'evernote',
            'skydrive',
            'sugarsync',
            'sharefile',
            'copy',
            'egnyte',
            's3',
            'sharepoint',
            'onedrivebiz',
            'hubspot',
            'salesforce',
            'smb',
            'azure',
            'cmis',
            'alfresco'
        ],
        file_store: [
            'dropbox',
            'gdrive',
            'box',
            'evernote',
            'skydrive',
            'sugarsync',
            'sharefile',
            'copy',
            'egnyte',
            'sharepoint',
            'onedrivebiz',
            'hubspot',
            'salesforce',
            'smb',
            'cmis',
            'alfresco'
        ],
        object_store: [
            'azure',
            's3']
    };

    var groups = [];
    if (config.services == undefined) {
        config.services = [];
        config.services = config.services.concat(services.file_store);
    } else if (config.services.length == 0) {
        config.services = [];
    } else {
        config.services = config.services.filter(function(service) {
          if (service in services) {
            groups = groups.concat(services[service]);
            return false;
          }
          return true;
        }).concat(groups);
    }

    // Type aliases.
    var aliases = {
      all: [
        'all'
      ],
      text: [
        'applescript',
        'as',
        'as3',
        'c',
        'cc',
        'clisp',
        'coffee',
        'cpp',
        'cs',
        'css',
        'csv',
        'cxx',
        'def',
        'diff',
        'erl',
        'fountain',
        'ft',
        'h',
        'hpp',
        'htm',
        'html',
        'hxx',
        'inc',
        'ini',
        'java',
        'js',
        'json',
        'less',
        'log',
        'lua',
        'm',
        'markdown',
        'mat',
        'md',
        'mdown',
        'mkdn',
        'mm',
        'mustache',
        'mxml',
        'patch',
        'php',
        'phtml',
        'pl',
        'plist',
        'properties',
        'py',
        'rb',
        'sass',
        'scss',
        'sh',
        'shtml',
        'sql',
        'tab',
        'taskpaper',
        'tex',
        'text',
        'tmpl',
        'tsv',
        'txt',
        'url',
        'vb',
        'xhtml',
        'xml',
        'yaml',
        'yml',
        ''],
      documents: [
        'csv',
        'doc',
        'dochtml',
        'docm',
        'docx',
        'docxml',
        'dot',
        'dothtml',
        'dotm',
        'dotx',
        'eps',
        'fdf',
        'key',
        'keynote',
        'kth',
        'mpd',
        'mpp',
        'mpt',
        'mpx',
        'nmbtemplate',
        'numbers',
        'odc',
        'odg',
        'odp',
        'ods',
        'odt',
        'pages',
        'pdf',
        'pdfxml',
        'pot',
        'pothtml',
        'potm',
        'potx',
        'ppa',
        'ppam',
        'pps',
        'ppsm',
        'ppsx',
        'ppt',
        'ppthtml',
        'pptm',
        'pptx',
        'pptxml',
        'prn',
        'ps',
        'pwz',
        'rtf',
        'tab',
        'template',
        'tsv',
        'txt',
        'vdx',
        'vsd',
        'vss',
        'vst',
        'vsx',
        'vtx',
        'wbk',
        'wiz',
        'wpd',
        'wps',
        'xdf',
        'xdp',
        'xlam',
        'xll',
        'xlr',
        'xls',
        'xlsb',
        'xlsm',
        'xlsx',
        'xltm',
        'xltx',
        'xps'],
      images: [
        'bmp',
        'cr2',
        'gif',
        'ico',
        'ithmb',
        'jpeg',
        'jpg',
        'nef',
        'png',
        'raw',
        'svg',
        'tif',
        'tiff',
        'wbmp',
        'webp'],
      videos: [
        '3g2',
        '3gp',
        '3gpp',
        '3gpp2',
        'asf',
        'avi',
        'dv',
        'dvi',
        'flv',
        'm2t',
        'm4v',
        'mkv',
        'mov',
        'mp4',
        'mpeg',
        'mpg',
        'mts',
        'ogv',
        'ogx',
        'rm',
        'rmvb',
        'ts',
        'vob',
        'webm',
        'wmv'],
      audio: [
        'aac',
        'aif',
        'aifc',
        'aiff',
        'au',
        'flac',
        'm4a',
        'm4b',
        'm4p',
        'm4r',
        'mid',
        'mp3',
        'oga',
        'ogg',
        'opus',
        'ra',
        'ram',
        'spx',
        'wav',
        'wma'],
      ebooks: [
        'acsm',
        'aeh',
        'azw',
        'cb7',
        'cba',
        'cbr',
        'cbt',
        'cbz',
        'ceb',
        'chm',
        'epub',
        'fb2',
        'ibooks',
        'kf8',
        'lit',
        'lrf',
        'lrx',
        'mobi',
        'opf',
        'oxps',
        'pdf',
        'pdg',
        'prc',
        'tebr',
        'tr2',
        'tr3',
        'xeb',
        'xps']
      }
      , additions = [];

    config.types = config.types.filter(function(type) {
      if (type in aliases) {
        additions = additions.concat(aliases[type]);
        return false;
      }
      return true;
    }).concat(additions);

    // remove any duplicates
    config.types = config.types.filter(function(elem, pos) {
        return config.types.indexOf(elem) == pos;
    });

    // default to 'all'
    if (config.types.length === 0) {
        config.types.push('all');
    }

    if (config.debug) {
        window.config = config;
    }

    return config;
  });
})();
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'DetailView',
  extends: 'foam.u2.View',

  requires: [
    'foam.core.Property',
    'foam.u2.DetailPropertyView'
  ],

  exports: [
    'controllerMode'
  ],

  properties: [
    {
      name: 'data',
      postSet: function(_, data) {
        if ( data && data.cls_ !== this.of ) this.of = data.cls_;
      }
    },
    {
//      type: 'Model',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'showActions'
    },
    {
      name: 'properties',
      expression: function(of) {
        if ( ! of ) return [];
        return of.getAxiomsByClass(foam.core.Property).
            filter(function(p) { return ! p.hidden; });
      }
    },
    {
      name: 'config'
      // Map of property-name: {map of property overrides} for configuring properties
      // values include 'label', 'units', and 'view'
    },
    {
      name: 'actions',
      expression: function(of) {
        return of.getAxiomsByClass(foam.core.Action);
      }
    },
    {
      name: 'controllerMode',
      attribute: true
    },
    {
      name: 'title',
      attribute: true,
      expression: function(of) { return of.label; },
      // documentation: function() {/*
      //
The display title for the $$DOC{ref:'foam.ui.View'}.
      //

      //*/}
    },
    [ 'nodeName', 'div' ]
  ],

  templates: [
    function CSS() {/*
      ^ {
        background: #fdfdfd;
        border: solid 1px #dddddd;
        box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
        display: inline-block;
        margin: 5px;
        padding: 3px;
      }
      ^ table {
        padding-bottom: 2px;
      }
      ^title {
        color: #333;
        float: left;
        font-size: 14px;
        font-weight: bold;
        margin-bottom: 8px;
        padding: 2px;
      }
      ^toolbar {
        margin-left: 5px;
      }
      ^ input {
        border: solid 1px #aacfe4;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        padding: 4px 2px;
      }
      ^ textarea {
        border: solid 1px #aacfe4;
        float: left;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        overflow: auto;
        padding: 4px 2px;
        width: 98%;
      }
      ^ select {
        border: solid 1px #aacfe4;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        padding: 4px 2px;
      }
    */}
  ],

  methods: [
    function initE() {
      var self = this;
      this.add(this.slot(function(model, properties) {
        if ( ! model ) return 'Set model or data.';

        var title = self.title && self.E('tr').
          start('td').cssClass(self.myCls('title')).attrs({colspan: 2}).
            add(this.title$).
          end();

        return self.actionBorder(
          self.
            E('table').
            cssClass(self.myCls()).
            add(title).
            add(properties.map(function(p) {
              var config = self.config && self.config[p.name];

              if ( config ) {
                p = p.clone();
                for ( var key in config ) {
                  p[key] = config[key];
                }
              }

              return self.DetailPropertyView.create({prop: p});
            })));
      }, this.of$, this.properties$));
    },

    function actionBorder(e) {
      if ( ! this.showActions || ! this.actions.length ) return e;

      return this.E().add(e).
        start('div').cssClass(this.myCls('toolbar')).add(this.actions).end();
    },

    function elementForFeature(fName) {
      var f = this.cls_.getFeature(fName) || this.X.data.model_.getFeature(fName);
      return f ? f.toE(this.Y) : this.E('Unknown feature: ' + fName).style({color: 'red'});
    }
  ]
});
<commit_msg>Added value asserting to DetailView.properties.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'DetailView',
  extends: 'foam.u2.View',

  requires: [
    'foam.core.Property',
    'foam.u2.DetailPropertyView'
  ],

  exports: [
    'controllerMode'
  ],

  properties: [
    {
      name: 'data',
      postSet: function(_, data) {
        if ( data && data.cls_ !== this.of ) this.of = data.cls_;
      }
    },
    {
//      type: 'Model',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'showActions'
    },
    {
      name: 'properties',
      // TODO: Make an FObjectArray when it validates properly
      preSet: function(_, ps) {
        this.assert(ps, 'Properties required.');
        for ( var i = 0 ; i < ps.length ; i++ ) {
          this.assert(
              foam.core.Propert.isInstance(ps),
              "Non-Property in 'properties' list:",
              ps);
        }
        return ps;
      },
      expression: function(of) {
        if ( ! of ) return [];
        return of.getAxiomsByClass(foam.core.Property).
            filter(function(p) { return ! p.hidden; });
      }
    },
    {
      name: 'config'
      // Map of property-name: {map of property overrides} for configuring properties
      // values include 'label', 'units', and 'view'
    },
    {
      name: 'actions',
      expression: function(of) {
        return of.getAxiomsByClass(foam.core.Action);
      }
    },
    {
      name: 'controllerMode',
      attribute: true
    },
    {
      name: 'title',
      attribute: true,
      expression: function(of) { return of.label; },
      // documentation: function() {/*
      //
The display title for the $$DOC{ref:'foam.ui.View'}.
      //

      //*/}
    },
    [ 'nodeName', 'div' ]
  ],

  templates: [
    function CSS() {/*
      ^ {
        background: #fdfdfd;
        border: solid 1px #dddddd;
        box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
        display: inline-block;
        margin: 5px;
        padding: 3px;
      }
      ^ table {
        padding-bottom: 2px;
      }
      ^title {
        color: #333;
        float: left;
        font-size: 14px;
        font-weight: bold;
        margin-bottom: 8px;
        padding: 2px;
      }
      ^toolbar {
        margin-left: 5px;
      }
      ^ input {
        border: solid 1px #aacfe4;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        padding: 4px 2px;
      }
      ^ textarea {
        border: solid 1px #aacfe4;
        float: left;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        overflow: auto;
        padding: 4px 2px;
        width: 98%;
      }
      ^ select {
        border: solid 1px #aacfe4;
        font-size: 10px;
        margin: 2px 0 0px 2px;
        padding: 4px 2px;
      }
    */}
  ],

  methods: [
    function initE() {
      var self = this;
      this.add(this.slot(function(model, properties) {
        if ( ! model ) return 'Set model or data.';

        var title = self.title && self.E('tr').
          start('td').cssClass(self.myCls('title')).attrs({colspan: 2}).
            add(this.title$).
          end();

        return self.actionBorder(
          self.
            E('table').
            cssClass(self.myCls()).
            add(title).
            add(properties.map(function(p) {
              var config = self.config && self.config[p.name];

              if ( config ) {
                p = p.clone();
                for ( var key in config ) {
                  p[key] = config[key];
                }
              }

              return self.DetailPropertyView.create({prop: p});
            })));
      }));
    },

    function actionBorder(e) {
      if ( ! this.showActions || ! this.actions.length ) return e;

      return this.E().add(e).
        start('div').cssClass(this.myCls('toolbar')).add(this.actions).end();
    },

    function elementForFeature(fName) {
      var f = this.cls_.getFeature(fName) || this.X.data.model_.getFeature(fName);
      return f ? f.toE(this.Y) : this.E('Unknown feature: ' + fName).style({color: 'red'});
    }
  ]
});
<|endoftext|>


<commit_before>module.exports = {
    syntax: require("postcss-scss"),
    plugins: [
        require("autoprefixer")
    ]
};
<commit_msg>last 2 versions<commit_after>module.exports = {
    syntax: require("postcss-scss"),
    plugins: [
        require("autoprefixer")({
            browsers: ["last 2 versions"]
        })
    ]
};
<|endoftext|>


<commit_before>const PostcssNormalize = require('postcss-normalize');
const PostcssPresetEnv = require('postcss-preset-env');

module.exports = {
	plugins: [
		PostcssPresetEnv(),
		PostcssNormalize()
	]
}
<commit_msg>Fussy semicolon addition for consistency<commit_after>const PostcssNormalize = require('postcss-normalize');
const PostcssPresetEnv = require('postcss-preset-env');

module.exports = {
	plugins: [
		PostcssPresetEnv(),
		PostcssNormalize()
	]
};
<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { StyleSheet } from 'react-native';

import { appStyles, COMPONENT_HEIGHT } from './appStyles';
import { authStyles } from './authStyles';
import { buttonStyles } from './buttonStyles';
import { confirmModalStyles } from './confirmModalStyles';
import { dataTableStyles, dataTableColors } from './dataTableStyles';
import { loadingIndicatorStyles } from './loadingIndicatorStyles';
import { modalStyles } from './modalStyles';
import { navigationStyles } from './navigationStyles';
import {
  pageStyles,
  expansionPageStyles,
  PAGE_CONTENT_PADDING_BOTTOM,
  PAGE_CONTENT_PADDING_TOP,
  PAGE_CONTENT_PADDING_HORIZONTAL,
  FULL_SCREEN_MODAL_MARGIN,
} from './pageStyles';
import { toggleBarStyles } from './toggleBarStyles';
import newPageStyles from './newPageStyles';
import newDataTableStyles from './newDataTableStyles';

export {
  BACKGROUND_COLOR,
  BLUE_WHITE,
  DARK_GREY,
  DARKER_GREY,
  FINALISE_GREEN,
  FINALISED_RED,
  GREY,
  LIGHT_GREY,
  ROW_BLUE,
  SHADOW_BORDER,
  SOFT_RED,
  SUSSOL_ORANGE,
  WARM_GREY,
  WARMER_GREY,
} from './colors';

export { APP_FONT_FAMILY } from './fonts';

export { textStyles } from './textStyles';

export {
  COMPONENT_HEIGHT,
  newPageStyles,
  newDataTableStyles,
  dataTableStyles,
  dataTableColors,
  pageStyles,
  expansionPageStyles,
  FULL_SCREEN_MODAL_MARGIN,
  PAGE_CONTENT_PADDING_BOTTOM,
  PAGE_CONTENT_PADDING_TOP,
  PAGE_CONTENT_PADDING_HORIZONTAL,
};

export default StyleSheet.create({
  ...appStyles,
  ...authStyles,
  ...buttonStyles,
  ...confirmModalStyles,
  ...loadingIndicatorStyles,
  ...modalStyles,
  ...navigationStyles,
  ...pageStyles,
  ...toggleBarStyles,
});
<commit_msg>Add remove expansion styles from index<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import { StyleSheet } from 'react-native';

import { appStyles, COMPONENT_HEIGHT } from './appStyles';
import { authStyles } from './authStyles';
import { buttonStyles } from './buttonStyles';
import { confirmModalStyles } from './confirmModalStyles';
import { dataTableStyles, dataTableColors } from './dataTableStyles';
import { loadingIndicatorStyles } from './loadingIndicatorStyles';
import { modalStyles } from './modalStyles';
import { navigationStyles } from './navigationStyles';
import {
  PAGE_CONTENT_PADDING_BOTTOM,
  PAGE_CONTENT_PADDING_TOP,
  PAGE_CONTENT_PADDING_HORIZONTAL,
  FULL_SCREEN_MODAL_MARGIN,
  pageStyles,
} from './pageStyles';
import { toggleBarStyles } from './toggleBarStyles';
import newPageStyles from './newPageStyles';
import newDataTableStyles from './newDataTableStyles';

export {
  BACKGROUND_COLOR,
  BLUE_WHITE,
  DARK_GREY,
  DARKER_GREY,
  FINALISE_GREEN,
  FINALISED_RED,
  GREY,
  LIGHT_GREY,
  ROW_BLUE,
  SHADOW_BORDER,
  SOFT_RED,
  SUSSOL_ORANGE,
  WARM_GREY,
  WARMER_GREY,
} from './colors';

export { APP_FONT_FAMILY } from './fonts';

export { textStyles } from './textStyles';

export {
  COMPONENT_HEIGHT,
  newPageStyles,
  newDataTableStyles,
  dataTableStyles,
  dataTableColors,
  FULL_SCREEN_MODAL_MARGIN,
  PAGE_CONTENT_PADDING_BOTTOM,
  PAGE_CONTENT_PADDING_TOP,
  PAGE_CONTENT_PADDING_HORIZONTAL,
};

export default StyleSheet.create({
  ...appStyles,
  ...authStyles,
  ...buttonStyles,
  ...confirmModalStyles,
  ...loadingIndicatorStyles,
  ...modalStyles,
  ...navigationStyles,
  ...pageStyles,
  ...toggleBarStyles,
});
<|endoftext|>


<commit_before>'use strict';

/*
 * An Simple AngularJS Gravatar Directive
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('ui-gravatar', ['md5']).
    factory('gravatarImageService', function (md5) {
        return {
            getImageSrc : function(value, size, rating, defaultUrl, secure) {
                // convert the value to lower case and then to a md5 hash
                var hash = md5.createHash(value.toLowerCase());
                var src = (secure ? 'https://secure' : 'http://www' ) + '.gravatar.com/avatar/' + hash + '?s=' + size + '&r=' + rating + '&d=' + defaultUrl;
                return src;
            }
        };
    }).
    directive('gravatarImage', ['gravatarImageService', function (gravatarImageService) {
        return {
            restrict:"EAC",
            link:function (scope, elm, attrs) {
                // by default the values will come in as undefined so we need to setup a
                // watch to notify us when the value changes
                scope.$watch(attrs.gravatarEmail, function (value) {
                    // let's do nothing if the value comes in empty, null or undefined
                    if ((value !== null) && (value !== undefined) && (value !== '') && (null != value.match(/.*@.*\..{2}/))) {
                        // parse the size attribute
                        var size = attrs.gravatarSize || 40;
                        // parse the ratings attribute
                        var rating = attrs.gravatarRating || 'pg';
                        // parse the default image url
                        var defaultUrl = attrs.gravatarDefault || '404';
                        // parse css class
                        var cssClass = attrs.gravatarCssClass || 'gravatar-icon';
                        // get image src from service
                        var src = gravatarImageService.getImageSrc(value, size, rating, defaultUrl, attrs.gravatarSecure);
                        // construct the tag to insert into the element
                        var tag = '';
                        //remove any existing imgs
                        elm.find('img').remove();
                        // insert the tag into the element
                        elm.append(tag);
                    }
                });
            }};
    }]);
<commit_msg>Made getImageSrc arguments optional<commit_after>'use strict';

/*
 * An Simple AngularJS Gravatar Directive
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('ui-gravatar', ['md5']).
    factory('gravatarImageService', function (md5) {
        return {
            getImageSrc : function(value, size, rating, defaultUrl, secure) {
                // convert the value to lower case and then to a md5 hash
                var hash = md5.createHash(value.toLowerCase());
                var src = (secure ? 'https://secure' : 'http://www' ) + '.gravatar.com/avatar/' + hash;
                if (size) src += '?s=' + size;
                if (rating) src += '&r=' + rating;
                if (defaultUrl) src += '&d=' + defaultUrl;
                return src;
            }
        };
    }).
    directive('gravatarImage', ['gravatarImageService', function (gravatarImageService) {
        return {
            restrict:"EAC",
            link:function (scope, elm, attrs) {
                // by default the values will come in as undefined so we need to setup a
                // watch to notify us when the value changes
                scope.$watch(attrs.gravatarEmail, function (value) {
                    // let's do nothing if the value comes in empty, null or undefined
                    if ((value !== null) && (value !== undefined) && (value !== '') && (null != value.match(/.*@.*\..{2}/))) {
                        // parse the size attribute
                        var size = attrs.gravatarSize || 40;
                        // parse the ratings attribute
                        var rating = attrs.gravatarRating || 'pg';
                        // parse the default image url
                        var defaultUrl = attrs.gravatarDefault || '404';
                        // parse css class
                        var cssClass = attrs.gravatarCssClass || 'gravatar-icon';
                        // get image src from service
                        var src = gravatarImageService.getImageSrc(value, size, rating, defaultUrl, attrs.gravatarSecure);
                        // construct the tag to insert into the element
                        var tag = '';
                        //remove any existing imgs
                        elm.find('img').remove();
                        // insert the tag into the element
                        elm.append(tag);
                    }
                });
            }};
    }]);
<|endoftext|>


<commit_before>'use strict';

angular.module('mgcrea.ngStrap.helpers.dimensions', [])

  .factory('dimensions', function($document, $window) {

    var jqLite = angular.element;
    var fn = {};

    /**
     * Test the element nodeName
     * @param element
     * @param name
     */
    var nodeName = fn.nodeName = function(element, name) {
      return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();
    };

    /**
     * Returns the element computed style
     * @param element
     * @param prop
     * @param extra
     */
    fn.css = function(element, prop, extra) {
      var value;
      if (element.currentStyle) { //IE
        value = element.currentStyle[prop];
      } else if (window.getComputedStyle) {
        value = window.getComputedStyle(element)[prop];
      } else {
        value = element.style[prop];
      }
      return extra === true ? parseFloat(value) || 0 : value;
    };

    /**
     * Provides read-only equivalent of jQuery's offset function:
     * @required-by bootstrap-tooltip, bootstrap-affix
     * @url http://api.jquery.com/offset/
     * @param element
     */
    fn.offset = function(element) {
      var boxRect = element.getBoundingClientRect();
      var docElement = element.ownerDocument;
      return {
        width: boxRect.width || element.offsetWidth,
        height: boxRect.height || element.offsetHeight,
        top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),
        left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)
      };
    };

    /**
     * Provides read-only equivalent of jQuery's position function
     * @required-by bootstrap-tooltip, bootstrap-affix
     * @url http://api.jquery.com/offset/
     * @param element
     */
    fn.position = function(element) {

      var offsetParentRect = {top: 0, left: 0},
          offsetParentElement,
          offset;

      // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
      if (fn.css(element, 'position') === 'fixed') {

        // We assume that getBoundingClientRect is available when computed position is fixed
        offset = element.getBoundingClientRect();

      } else {

        // Get *real* offsetParentElement
        offsetParentElement = offsetParent(element);
        offset = fn.offset(element);

        // Get correct offsets
        offset = fn.offset(element);
        if (!nodeName(offsetParentElement, 'html')) {
          offsetParentRect = fn.offset(offsetParentElement);
        }

        // Add offsetParent borders
        offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);
        offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);
      }

      // Subtract parent offsets and element margins
      return {
        width: element.offsetWidth,
        height: element.offsetHeight,
        top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),
        left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)
      };

    };

    /**
     * Returns the closest, non-statically positioned offsetParent of a given element
     * @required-by fn.position
     * @param element
     */
    var offsetParent = function offsetParentElement(element) {
      var docElement = element.ownerDocument;
      var offsetParent = element.offsetParent || docElement;
      if(nodeName(offsetParent, '#document')) return docElement.documentElement;
      while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {
        offsetParent = offsetParent.offsetParent;
      }
      return offsetParent || docElement.documentElement;
    };

    /**
     * Provides equivalent of jQuery's height function
     * @required-by bootstrap-affix
     * @url http://api.jquery.com/height/
     * @param element
     * @param outer
     */
    fn.height = function(element, outer) {
      var value = element.offsetHeight;
      if(outer) {
        value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);
      } else {
        value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);
      }
      return value;
    };

    /**
     * Provides equivalent of jQuery's width function
     * @required-by bootstrap-affix
     * @url http://api.jquery.com/width/
     * @param element
     * @param outer
     */
    fn.width = function(element, outer) {
      var value = element.offsetWidth;
      if(outer) {
        value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);
      } else {
        value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);
      }
      return value;
    };

    return fn;

  });
<commit_msg>fix(dimensions) removing redundant offset calc<commit_after>'use strict';

angular.module('mgcrea.ngStrap.helpers.dimensions', [])

  .factory('dimensions', function($document, $window) {

    var jqLite = angular.element;
    var fn = {};

    /**
     * Test the element nodeName
     * @param element
     * @param name
     */
    var nodeName = fn.nodeName = function(element, name) {
      return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();
    };

    /**
     * Returns the element computed style
     * @param element
     * @param prop
     * @param extra
     */
    fn.css = function(element, prop, extra) {
      var value;
      if (element.currentStyle) { //IE
        value = element.currentStyle[prop];
      } else if (window.getComputedStyle) {
        value = window.getComputedStyle(element)[prop];
      } else {
        value = element.style[prop];
      }
      return extra === true ? parseFloat(value) || 0 : value;
    };

    /**
     * Provides read-only equivalent of jQuery's offset function:
     * @required-by bootstrap-tooltip, bootstrap-affix
     * @url http://api.jquery.com/offset/
     * @param element
     */
    fn.offset = function(element) {
      var boxRect = element.getBoundingClientRect();
      var docElement = element.ownerDocument;
      return {
        width: boxRect.width || element.offsetWidth,
        height: boxRect.height || element.offsetHeight,
        top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),
        left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)
      };
    };

    /**
     * Provides read-only equivalent of jQuery's position function
     * @required-by bootstrap-tooltip, bootstrap-affix
     * @url http://api.jquery.com/offset/
     * @param element
     */
    fn.position = function(element) {

      var offsetParentRect = {top: 0, left: 0},
          offsetParentElement,
          offset;

      // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
      if (fn.css(element, 'position') === 'fixed') {

        // We assume that getBoundingClientRect is available when computed position is fixed
        offset = element.getBoundingClientRect();

      } else {

        // Get *real* offsetParentElement
        offsetParentElement = offsetParent(element);

        // Get correct offsets
        offset = fn.offset(element);
        if (!nodeName(offsetParentElement, 'html')) {
          offsetParentRect = fn.offset(offsetParentElement);
        }

        // Add offsetParent borders
        offsetParentRect.top += fn.css(offsetParentElement, 'borderTopWidth', true);
        offsetParentRect.left += fn.css(offsetParentElement, 'borderLeftWidth', true);
      }

      // Subtract parent offsets and element margins
      return {
        width: element.offsetWidth,
        height: element.offsetHeight,
        top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),
        left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)
      };

    };

    /**
     * Returns the closest, non-statically positioned offsetParent of a given element
     * @required-by fn.position
     * @param element
     */
    var offsetParent = function offsetParentElement(element) {
      var docElement = element.ownerDocument;
      var offsetParent = element.offsetParent || docElement;
      if(nodeName(offsetParent, '#document')) return docElement.documentElement;
      while(offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {
        offsetParent = offsetParent.offsetParent;
      }
      return offsetParent || docElement.documentElement;
    };

    /**
     * Provides equivalent of jQuery's height function
     * @required-by bootstrap-affix
     * @url http://api.jquery.com/height/
     * @param element
     * @param outer
     */
    fn.height = function(element, outer) {
      var value = element.offsetHeight;
      if(outer) {
        value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);
      } else {
        value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);
      }
      return value;
    };

    /**
     * Provides equivalent of jQuery's width function
     * @required-by bootstrap-affix
     * @url http://api.jquery.com/width/
     * @param element
     * @param outer
     */
    fn.width = function(element, outer) {
      var value = element.offsetWidth;
      if(outer) {
        value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);
      } else {
        value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);
      }
      return value;
    };

    return fn;

  });
<|endoftext|>


<commit_before>'use babel'

import FS from 'fs'
import Path from 'path'
import Minimatch from 'minimatch'
import isGlob from 'is-glob'
import {DEFAULT_IGNORED} from '../defaults'
import {isIgnored} from './common'

export function findFiles(pathGiven, ignoredGiven, state) {
  const ignored = DEFAULT_IGNORED.concat(ignoredGiven)

  if (isGlob(pathGiven)) {
    return findFilesGlob(pathGiven, ignored, state)
  } else {
    const path = Path.isAbsolute(pathGiven) ? pathGiven : Path.join(state.root, pathGiven)
    const stat = FS.statSync(path)

    if (stat.isFile()) {
      return [Path.relative(state.root, path)]
    } else if (stat.isDirectory()) {
      return findFilesRegular(path, ignored, state)
    } else {
      throw new Error(`${path} is neither a file nor a directory`)
    }
  }
}

export function findFilesBase(path, ignored, {root, config}, validateCallback) {
  let files = []

  // TODO: Only include files that are used in config
  FS.readdirSync(path).forEach(function(entryName) {
    const paths = {}
    paths.absolute = Path.join(path, entryName)
    paths.relative = Path.relative(root, paths.absolute)
    paths.name = entryName
    const stat = FS.lstatSync(paths.absolute)

    if (entryName.substr(0, 1) === '.' ||
        stat.isSymbolicLink() ||
        isIgnored(paths.name, paths.relative, ignored)) {
      return
    }

    if (validateCallback === null || validateCallback(paths, stat)) {
      if (stat.isDirectory()) {
        files = files.concat(findFilesBase(paths.absolute, ignored, {root, config}, validateCallback))
      } else if (stat.isFile()) {
        files.push(paths.relative)
      }
    }
  })

  return files
}

export function findFilesRegular(path, ignored, {root, config}) {
  return findFilesBase(path, ignored, {root, config}, null)
}

export function findFilesGlob(path, ignored, {root, config}) {
  return findFilesBase(root, ignored, {root, config}, function({absolute, relative, name}, stat) {
    if (stat.isDirectory()) {
      return true
    }
    return Minimatch(relative, path)
  })
}
<commit_msg>:art: Cleanup find-files helper<commit_after>'use babel'

import FS from 'fs'
import Path from 'path'
import Minimatch from 'minimatch'
import isGlob from 'is-glob'
import {DEFAULT_IGNORED} from '../defaults'
import {isIgnored} from './common'

export function findFiles(pathGiven, ignoredGiven, options) {
  const ignored = DEFAULT_IGNORED.concat(ignoredGiven)

  if (isGlob(pathGiven)) {
    return findFilesGlob(pathGiven, ignored, options)
  } else {
    const path = Path.isAbsolute(pathGiven) ? pathGiven : Path.join(options.root, pathGiven)
    const stat = FS.statSync(path)

    if (stat.isFile()) {
      return [Path.relative(options.root, path)]
    } else if (stat.isDirectory()) {
      return findFilesRegular(path, ignored, options)
    } else {
      throw new Error(`${path} is neither a file nor a directory`)
    }
  }
}

export function findFilesBase(path, ignored, {root, config}, validateCallback) {
  let files = []

  // TODO: Only include files that are used in config
  FS.readdirSync(path).forEach(function(entryName) {
    const absolutePath = Path.join(path, entryName)
    const relativePath = Path.relative(root, absolutePath)
    const stat = FS.lstatSync(absolutePath)

    if (entryName.substr(0, 1) === '.' ||
        stat.isSymbolicLink() ||
        isIgnored(entryName, relativePath, ignored)) {
      return
    }

    if (validateCallback === null || validateCallback(relativePath, stat)) {
      if (stat.isDirectory()) {
        files = files.concat(findFilesBase(absolutePath, ignored, {root, config}, validateCallback))
      } else if (stat.isFile()) {
        files.push({relativePath, absolutePath})
      }
    }
  })

  return files
}

export function findFilesRegular(path, ignored, {root, config}) {
  return findFilesBase(path, ignored, {root, config}, null)
}

export function findFilesGlob(path, ignored, {root, config}) {
  return findFilesBase(root, ignored, {root, config}, function(relative, stat) {
    return stat.isDirectory() || Minimatch(relative, path)
  })
}
<|endoftext|>


<commit_before>"use strict";

define([
    'backbone',
    './PointModel'
], function(Backbone, PointModel) {

    var Collection =  Backbone.Collection.extend({
        model: PointModel
    });

    var collection = new Collection();

    collection.add({
        latitude:  51.5085300,
        longitude: -0.1257400,
        name: "London"
    });

    collection.add({
        latitude: 40.7142700,
        longitude:  -74.0059700,
        name: "NewYork"
    });

    collection.add({
        latitude:  55.7522200,
        longitude:  37.6155600,
        name: "Moskow"
    });

    collection.add({
        latitude:  -33.8678500,
        longitude: 151.2073200,
        name: "Sydney"
    });

    collection.add({
        latitude:   -34.6131500,
        longitude:  -58.3772300,
        name: "Buenos Aires"
    });

    return collection;
});
<commit_msg>Fix typo<commit_after>"use strict";

define([
    'backbone',
    './PointModel'
], function(Backbone, PointModel) {

    var Collection =  Backbone.Collection.extend({
        model: PointModel
    });

    var collection = new Collection();

    collection.add({
        latitude:  51.5085300,
        longitude: -0.1257400,
        name: "London"
    });

    collection.add({
        latitude: 40.7142700,
        longitude:  -74.0059700,
        name: "New York"
    });

    collection.add({
        latitude:  55.7522200,
        longitude:  37.6155600,
        name: "Moscow"
    });

    collection.add({
        latitude:  -33.8678500,
        longitude: 151.2073200,
        name: "Sydney"
    });

    collection.add({
        latitude:   -34.6131500,
        longitude:  -58.3772300,
        name: "Buenos Aires"
    });

    return collection;
});
<|endoftext|>