<commit_before>import assertKeys from './assert-keys'
import compareCourseToQualification from './compare-course-to-qualification'
import filter from 'lodash/collection/filter'
import flatten from 'lodash/array/flatten'
import forEach from 'lodash/collection/forEach'
import has from 'lodash/object/has'
import isPlainObject from 'lodash/lang/isPlainObject'
import max from 'lodash/collection/max'
import min from 'lodash/collection/min'
import pluck from 'lodash/collection/pluck'
import simplifyCourse from './simplify-course'
import uniq from 'lodash/array/uniq'

export default function filterByWhereClause(baseList, clause, fullList) {
	// When filtering by an and-clause, we need access to both the
	// entire list of courses, and the result of the prior iteration.
	// To simplify future invocations, we default to `fullList = list`
	if (!fullList) {
		fullList = baseList
	}

	// There are only two types of where-clauses: boolean, and qualification.
	// Boolean where-clauses are comprised of a set of qualifications.

	// This function always reduces down to a call to filterByQualification
	if (clause.$type === 'qualification') {
		return filterByQualification(baseList, clause, fullList)
	}

	// either an and- or or-clause.
	else if (clause.$type === 'boolean') {
		// and-clauses become the result of applying each invocation to the
		// result of the prior one. they are the list of unique courses which
		// meet all of the qualifications.
		if (has(clause, '$and')) {
			let filtered = baseList
			forEach(clause.$and, q => {
				filtered = filterByWhereClause(filtered, q, fullList)
			})
			return filtered
		}

		// or-clauses are the list of unique courses that meet one or more
		// of the qualifications.
		else if (has(clause, '$or')) {
			let filtrations = []
			forEach(clause.$or, q => {
				filtrations = filtrations.concat(filterByWhereClause(baseList, q))
			})

			// join together the list of lists of possibilities,
			// then uniquify them by way of turning them into the simplified representations.
			return uniq(filtrations, simplifyCourse)
		}

		// only 'and' and 'or' are currently supported.
		else {
			throw new TypeError(`filterByWhereClause(): neither $or nor $and could be found in ${JSON.stringify(clause)}`)
		}
	}

	// where-clauses *must* be either a 'boolean' or a 'qualification'
	else {
		throw new TypeError(`filterByWhereClause(): wth kind of type is a "${clause.$type}" clause?`)
	}
}

export function filterByQualification(list, qualification, fullList) {
	assertKeys(qualification, '$key', '$operator', '$value')
	const value = qualification.$value

	if (isPlainObject(value)) {
		if (value.$type === 'function') {
			let func = undefined
			if (value.$name === 'max') {
				func = max
			}
			else if (value.$name === 'min') {
				func = min
			}
			else {
				throw new ReferenceError(`filterByQualification(): ${value.$name} is not a valid function to call.`)
			}
			const complete = fullList || list
			const filtered = filterByWhereClause(complete, value.$where)
			const items = pluck(filtered, value.$prop)
			const computed = func(items)
			// console.log('looked at', complete)
			// console.log('reduced to', filtered)
			// console.log('came up with', computed)
			value['$computed-value'] = computed
		}
		else {
			throw new TypeError(`filterByQualification(): ${value.$type} is not a valid type for a query.`)
		}
	}

	const filtered = filter(list, course =>
		compareCourseToQualification(course, qualification))

	return filtered
}
<commit_msg>use a lookup object in filterByWhereClause<commit_after>import assertKeys from './assert-keys'
import compareCourseToQualification from './compare-course-to-qualification'
import filter from 'lodash/collection/filter'
import flatten from 'lodash/array/flatten'
import forEach from 'lodash/collection/forEach'
import has from 'lodash/object/has'
import isPlainObject from 'lodash/lang/isPlainObject'
import max from 'lodash/collection/max'
import min from 'lodash/collection/min'
import pluck from 'lodash/collection/pluck'
import simplifyCourse from './simplify-course'
import uniq from 'lodash/array/uniq'

export default function filterByWhereClause(baseList, clause, fullList) {
	// When filtering by an and-clause, we need access to both the
	// entire list of courses, and the result of the prior iteration.
	// To simplify future invocations, we default to `fullList = list`
	if (!fullList) {
		fullList = baseList
	}

	// There are only two types of where-clauses: boolean, and qualification.
	// Boolean where-clauses are comprised of a set of qualifications.

	// This function always reduces down to a call to filterByQualification
	if (clause.$type === 'qualification') {
		return filterByQualification(baseList, clause, fullList)
	}

	// either an and- or or-clause.
	else if (clause.$type === 'boolean') {
		// and-clauses become the result of applying each invocation to the
		// result of the prior one. they are the list of unique courses which
		// meet all of the qualifications.
		if (has(clause, '$and')) {
			let filtered = baseList
			forEach(clause.$and, q => {
				filtered = filterByWhereClause(filtered, q, fullList)
			})
			return filtered
		}

		// or-clauses are the list of unique courses that meet one or more
		// of the qualifications.
		else if (has(clause, '$or')) {
			let filtrations = []
			forEach(clause.$or, q => {
				filtrations = filtrations.concat(filterByWhereClause(baseList, q))
			})

			// join together the list of lists of possibilities,
			// then uniquify them by way of turning them into the simplified representations.
			return uniq(filtrations, simplifyCourse)
		}

		// only 'and' and 'or' are currently supported.
		else {
			throw new TypeError(`filterByWhereClause(): neither $or nor $and could be found in ${JSON.stringify(clause)}`)
		}
	}

	// where-clauses *must* be either a 'boolean' or a 'qualification'
	else {
		throw new TypeError(`filterByWhereClause(): wth kind of type is a "${clause.$type}" clause?`)
	}
}

const qualificationFunctionLookup = {
	max: max,
	min: min,
}

export function filterByQualification(list, qualification, fullList) {
	assertKeys(qualification, '$key', '$operator', '$value')
	const value = qualification.$value

	if (isPlainObject(value)) {
		if (value.$type === 'function') {
			const func = qualificationFunctionLookup[value.$name]

			if (!func) {
				throw new ReferenceError(`filterByQualification(): ${value.$name} is not a valid function to call.`)
			}
			const complete = fullList || list
			const filtered = filterByWhereClause(complete, value.$where)
			const items = pluck(filtered, value.$prop)
			const computed = func(items)
			// console.log('looked at', complete)
			// console.log('reduced to', filtered)
			// console.log('came up with', computed)
			value['$computed-value'] = computed
		}
		else {
			throw new TypeError(`filterByQualification(): ${value.$type} is not a valid type for a query.`)
		}
	}

	const filtered = filter(list, course =>
		compareCourseToQualification(course, qualification))

	return filtered
}
<|endoftext|>


<commit_before>/**
 * AlMighty page object example module for openshift.io start page
 * See: http://martinfowler.com/bliki/PageObject.html,
 * https://www.thoughtworks.com/insights/blog/using-page-objects-overcome-protractors-shortcomings
 * @author ldimaggi@redhat.com
 */

'use strict';

/*
 * openshift.io Start Page Definition
 */

var testSupport = require('../testSupport'),
    constants = require("../constants"),
    OpenShiftIoDashboardPage = require('../page-objects/openshift-io-dashboard.page'),
    OpenShiftIoGithubLoginPage = require('../page-objects/openshift-io-github-login.page');

var until = protractor.ExpectedConditions;

class OpenShiftIoRHDLoginPage {

  constructor() {
  };

  doLogin(browser) {
    this.clickRhdUsernameField();
    this.typeRhdUsernameField(browser.params.login.user);
    this.clickRhdPasswordField();
    this.typeRhdPasswordField(browser.params.login.password);
    return this.clickRhdLoginButton();
  }

  /* Social media login buttons */

  get githubLoginButton () {
     return element(by.css("#social-github"));
  }
  clickGithubLoginButton () {
    browser.wait(until.presenceOf(this.githubLoginButton), constants.WAIT, 'Failed to find github login');
    this.githubLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:githubLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get stackoverflowLoginButton () {
     return element(by.css("#social-stackoverflow"));
  }
  clickStackoverflowLoginButton () {
    browser.wait(until.presenceOf(this.stackoverflowLoginButton), constants.WAIT, 'Failed to find stackoverflow login');
    this.stackoverflowLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:stackoverflowLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get linkedinLoginButton () {
     return element(by.css(".fa.fa-linkedin-square"));
  }
  clickLinkedinLoginButton () {
    browser.wait(until.presenceOf(this.linkedinLoginButton), constants.WAIT, 'Failed to find linked in login');
    this.linkedinLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:linkedinLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get twitterLoginButton () {
     return element(by.css("#social-twitter"));
  }
  clickTwitterLoginButton () {
    browser.wait(until.presenceOf(this.twitterLoginButton), constants.WAIT, 'Failed to find twitter login');
    this.twitterLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:twitterLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get facebookLoginButton () {
     return element(by.css("#social-facebook"));
  }
  clickFacebookLoginButton () {
    browser.wait(until.presenceOf(this.facebookLoginButton), constants.WAIT, 'Failed to find facebook login');
    this.facebookLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:facebookLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get googleLoginButton () {
     return element(by.css("#social-google"));
  }
  clickGoogleLoginButton () {
    browser.wait(until.presenceOf(this.googleLoginButton), constants.WAIT, 'Failed to find google login');
    this.googleLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:googleLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get microsoftLoginButton () {
     return element(by.css("#social-microsoft"));
  }
  clickMicrosoftLoginButton () {
    browser.wait(until.presenceOf(this.microsoftLoginButton), constants.WAIT, 'Failed to find microsoft login');
    this.microsoftLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:microsoftLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get jbossdeveloperLoginButton () {
     return element(by.css("#social-jbossdeveloper"));
  }
  clickJbossdeveloperLoginButton () {
    browser.wait(until.presenceOf(this.jbossdeveloperLoginButton), constants.WAIT, 'Failed to find jbossdeveloper login');
    this.jbossdeveloperLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:jbossdeveloperLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  /* Red Hat Developer Login */

  get rhdUsernameField () {
     return element(by.id("username"));
  }
  clickRhdUsernameField () {
     return this.rhdUsernameField.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:rhdUsernameField");
    });
    return;
  }
  typeRhdUsernameField (usernameString) {
     return this.rhdUsernameField.sendKeys(usernameString);
  }

  get rhdPasswordField () {
     return element(by.id("password"));
  }
  clickRhdPasswordField () {
     return this.rhdPasswordField.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:rhdPasswordField");
    });
    return;
  }
  typeRhdPasswordField (passwordString) {
     return this.rhdPasswordField.sendKeys(passwordString);
  }

  get rhdLoginButton () {
     return element(by.id("kc-login"));
  }
  clickRhdLoginButton () {
    browser.wait(until.presenceOf(this.rhdLoginButton), constants.WAIT, 'Failed to find RHD login');
    this.rhdLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:rhdLoginButton");
    });
    return new OpenShiftIoDashboardPage();
  }

}

module.exports = OpenShiftIoRHDLoginPage;
<commit_msg>fix(test): UI changes to label broek all EE test logins<commit_after>/**
 * AlMighty page object example module for openshift.io start page
 * See: http://martinfowler.com/bliki/PageObject.html,
 * https://www.thoughtworks.com/insights/blog/using-page-objects-overcome-protractors-shortcomings
 * @author ldimaggi@redhat.com
 */

'use strict';

/*
 * openshift.io Start Page Definition
 */

var testSupport = require('../testSupport'),
    constants = require("../constants"),
    OpenShiftIoDashboardPage = require('../page-objects/openshift-io-dashboard.page'),
    OpenShiftIoGithubLoginPage = require('../page-objects/openshift-io-github-login.page');

var until = protractor.ExpectedConditions;

class OpenShiftIoRHDLoginPage {

  constructor() {
  };

  doLogin(browser) {
    this.clickRhdUsernameField();
    this.typeRhdUsernameField(browser.params.login.user);
    this.clickRhdPasswordField();
    this.typeRhdPasswordField(browser.params.login.password);
    return this.clickRhdLoginButton();
  }

  /* Social media login buttons */

  get githubLoginButton () {
     return element(by.css("#social-github"));
  }
  clickGithubLoginButton () {
    browser.wait(until.presenceOf(this.githubLoginButton), constants.WAIT, 'Failed to find github login');
    this.githubLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:githubLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get stackoverflowLoginButton () {
     return element(by.css("#social-stackoverflow"));
  }
  clickStackoverflowLoginButton () {
    browser.wait(until.presenceOf(this.stackoverflowLoginButton), constants.WAIT, 'Failed to find stackoverflow login');
    this.stackoverflowLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:stackoverflowLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get linkedinLoginButton () {
     return element(by.css(".fa.fa-linkedin-square"));
  }
  clickLinkedinLoginButton () {
    browser.wait(until.presenceOf(this.linkedinLoginButton), constants.WAIT, 'Failed to find linked in login');
    this.linkedinLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:linkedinLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get twitterLoginButton () {
     return element(by.css("#social-twitter"));
  }
  clickTwitterLoginButton () {
    browser.wait(until.presenceOf(this.twitterLoginButton), constants.WAIT, 'Failed to find twitter login');
    this.twitterLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:twitterLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get facebookLoginButton () {
     return element(by.css("#social-facebook"));
  }
  clickFacebookLoginButton () {
    browser.wait(until.presenceOf(this.facebookLoginButton), constants.WAIT, 'Failed to find facebook login');
    this.facebookLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:facebookLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get googleLoginButton () {
     return element(by.css("#social-google"));
  }
  clickGoogleLoginButton () {
    browser.wait(until.presenceOf(this.googleLoginButton), constants.WAIT, 'Failed to find google login');
    this.googleLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:googleLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get microsoftLoginButton () {
     return element(by.css("#social-microsoft"));
  }
  clickMicrosoftLoginButton () {
    browser.wait(until.presenceOf(this.microsoftLoginButton), constants.WAIT, 'Failed to find microsoft login');
    this.microsoftLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:microsoftLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  get jbossdeveloperLoginButton () {
     return element(by.css("#social-jbossdeveloper"));
  }
  clickJbossdeveloperLoginButton () {
    browser.wait(until.presenceOf(this.jbossdeveloperLoginButton), constants.WAIT, 'Failed to find jbossdeveloper login');
    this.jbossdeveloperLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:jbossdeveloperLoginButton");
    });
    return new OpenShiftIoGithubLoginPage();
  }

  /* Red Hat Developer Login */

  /* Username related changes caused by Sept 12, 2017 UI change - the username label is now
     displayed inside the username field - the label must be clicked before the username text is
     entered */
  get rhdUsernameFieldLabel () {
    return element(by.css(".login-username-field.field>label"));
  }
  get rhdUsernameField () {
    return element(by.id("username"));
  }
  clickRhdUsernameField () {
      browser.wait(until.elementToBeClickable(this.rhdUsernameFieldLabel), constants.LONG_WAIT, 'Failed to find rhdUsernameField');
      return this.rhdUsernameFieldLabel.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:rhdUsernameField");
    });
    return;
  }
  typeRhdUsernameField (usernameString) {
     return this.rhdUsernameField.sendKeys(usernameString);
  }

  get rhdPasswordField () {
     return element(by.id("password"));
  }
  clickRhdPasswordField () {
    browser.wait(until.elementToBeClickable(this.rhdPasswordField), constants.LONG_WAIT, 'Failed to find rhdPasswordField');
    return this.rhdPasswordField.click().then(function(){
       console.log("OpenShiftIoRHDLoginPage - clicked element:rhdPasswordField");
    });
    return;
  }
  typeRhdPasswordField (passwordString) {
     return this.rhdPasswordField.sendKeys(passwordString);
  }

  get rhdLoginButton () {
     return element(by.id("kc-login"));
  }
  clickRhdLoginButton () {
    browser.wait(until.presenceOf(this.rhdLoginButton), constants.WAIT, 'Failed to find RHD login');
    this.rhdLoginButton.click().then(function(){
      console.log("OpenShiftIoRHDLoginPage - clicked element:rhdLoginButton");
    });
    return new OpenShiftIoDashboardPage();
  }

}

module.exports = OpenShiftIoRHDLoginPage;
<|endoftext|>


<commit_before>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [
    {
      name      : 'TrackAliChile',
      script    : 'server/main.js'
    }
  ],
  /**
   * Deployment section
   * http://pm2.keymetrics.io/docs/usage/deployment/
   */
  deploy : {
    production : {
      user : 'dgacitua',
      host : [ 'dgacitua.info' ],
      ref  : 'origin/master',
      repo : 'git@github.com:dgacitua/TrackAliChile.git',
      path : '/var/www/production',
      'post-deploy' : 'npm install && npm run build && npm run deploy-client && pm2 reload ecosystem.config.js --env production',
      env  : {
        NODE_ENV: 'production'
      }
    },
    dev : {
      user : 'dgacitua',
      host : [ 'localhost' ],
      ref  : 'origin/master',
      repo : 'git@github.com:dgacitua/TrackAliChile.git',
      path : '/var/www/development',
      'post-deploy' : 'npm install && npm run build && npm run deploy-client && pm2 reload ecosystem.config.js --env production',
      env  : {
        NODE_ENV: 'dev'
      }
    }
  }
};
<commit_msg>PM2 Deploy Issues (2)<commit_after>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [
    {
      name      : 'TrackAliChile',
      script    : 'server/main.js'
    }
  ],
  /**
   * Deployment section
   * http://pm2.keymetrics.io/docs/usage/deployment/
   */
  deploy : {
    production : {
      user : 'dgacitua',
      host : [ 'dgacitua.info' ],
      ref  : 'origin/master',
      repo : 'git@github.com:dgacitua/TrackAliChile.git',
      path : '/var/www/trackalichile/production',
      'post-deploy' : 'npm install && npm run build && npm run deploy-client && pm2 reload ecosystem.config.js --env production',
      env  : {
        NODE_ENV: 'production'
      }
    },
    dev : {
      user : 'dgacitua',
      host : [ 'localhost' ],
      ref  : 'origin/master',
      repo : 'git@github.com:dgacitua/TrackAliChile.git',
      path : '/var/www/trackalichile/development',
      'post-deploy' : 'npm install && npm run build && npm run deploy-client && pm2 reload ecosystem.config.js --env production',
      env  : {
        NODE_ENV: 'dev'
      }
    }
  }
};
<|endoftext|>


<commit_before>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [

    // First application
    {
      name      : "autograph-server",
      script    : "app.js",
      env: {
        NODE_ENV: "development",
        PORT: 3001
      },
      env_production : {
        NODE_ENV: "production"
      },
      env_dev: {
        NODE_ENV: "development"
      }
    },

    // Second application
    {
      name      : "autograph-crawler",
      script    : "cron-job.js",
      env: {
        NODE_ENV: "development",
        PUBLIC_DIR: "public"
      },
      env_production: {
        NODE_ENV: "production",
        PUBLIC_DIR: ""
      }
    }
  ],

  /**
   * Deployment section
   * http://pm2.keymetrics.io/docs/usage/deployment/
   */
  deploy : {
    production : {
      user : "node",
      host : "212.83.163.1",
      ref  : "origin/master",
      repo : "git@github.com:FTChinese/autograph.git",
      path : "/var/www/production",
      "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production"
    },
    dev : {
      user : "node",
      host : "node.corp.ftchinese.com",
      ref  : "origin/master",
      repo : "git@github.com:FTChinese/autograph.git",
      path : "/data/git/ftacademy",
      "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env dev",
      env  : {
        NODE_ENV: "dev"
      }
    }
  }
}
<commit_msg>use same public dir for all process<commit_after>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [

    // First application
    {
      name      : "autograph-server",
      script    : "app.js",
      env: {
        NODE_ENV: "development",
        PORT: 3001
      },
      env_production : {
        NODE_ENV: "production",
        PUBLIC_DIR: ""
      }
    },

    // Second application
    {
      name      : "autograph-crawler",
      script    : "cron-job.js",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production",
        PUBLIC_DIR: ""
      }
    }
  ],

  /**
   * Deployment section
   * http://pm2.keymetrics.io/docs/usage/deployment/
   */
  deploy : {
    production : {
      user : "node",
      host : "212.83.163.1",
      ref  : "origin/master",
      repo : "git@github.com:FTChinese/autograph.git",
      path : "/var/www/production",
      "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production"
    },
    dev : {
      user : "node",
      host : "node.corp.ftchinese.com",
      ref  : "origin/master",
      repo : "git@github.com:FTChinese/autograph.git",
      path : "/data/git/ftacademy",
      "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env dev",
      env  : {
        NODE_ENV: "dev"
      }
    }
  }
}
<|endoftext|>


<commit_before>//dependencies
var helpers = require('./helperfunctions');
var filterHelpers = require('./filterhelpers.js');
var upload = require('./upload');
var resize = require('./resize');
var fs = require('fs');
var gm = require('gm');
var im = require('imagemagick');
var uuid = require('node-uuid');
var knox = require('knox');
var spawn = require('child_process').spawn;
var Q = require('q');

module.exports = {
  //route filter based on filter param
  routeFilter: function(req, res) {
    filters[req.filter](req, res);
  }
};

var filters = {
  blur : function(req, res) {
    //default values for radius and sigma of blur filter
    var rad = req.query.r || 2;
    var sig = req.query.s || 2;

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    //read file at requested path
    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .blur(rad, sig)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  charcoal: function(req, res) {
    //default value for charcoal factor
    var factor = req.query.f || 3;

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .charcoal(factor)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  channel: function(req, res) {
    //default value for color type
    var type = req.query.t || 'red';

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .channel(type)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  brighten: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(150, 80, 80)
    .gamma(1.2)
    .fill('#330000')
    .colorize(40)
    .contrast(+1)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  bw: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .colorspace('Gray')
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  sepia: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(115, 0, 100)
    .colorize(7, 21, 50)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  lomo: function(req, res) {
    console.log('red');
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .fill('#222b6d')
    .colorize(30)
    .modulate(90, 80, 100)
    .compose('Over')
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  gotham: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(120, 10, 100)
    .fill('#222b6d')
    .colorize(20)
    .gamma(0.5)
    .contrast()
    .contrast()
    .compose('Over')
    .borderColor('black')
    .border(7,7)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  //brighten

  bw_grad: function(req, res)  {
    var w;
    var h;
    var key = uuid.v4().split('-').pop();

    //obtain the dimensions of the requested image
    im.convert([process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', '-colorspace', 'gray', process.env.LOCAL_FILE_PATH + 'temp_' + req.key + '.jpg' ],
    function(err, stdout){
      if (err) {
        throw err;
      }

      im.identify(process.env.LOCAL_FILE_PATH + '/temp_' + req.key + '.jpg', function(err, features) {
        if (err) {
          console.error('could not process image </3');
          throw err;
        }

        w = features.width;
        h = features.height;

        Q.fcall(resize(req, res, w, h, key))
        .then(bw_grad2(req, res, key))
        .then(helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key ))
        .catch(function(err) {
          throw err;
        });

      });
    });
  },

  vintage: function(req, res) {
    var w;
    var h;
    var key = uuid.v4().split('-').pop();

    im.identify(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', function(err, features) {
      if (err) {
        console.error('could not process image </3');
        throw err;
      }

      w = features.width;
      h = features.height;

      resize(req, res, w, h, key);
    });
  }
};

var resize =  function(req, res, w, h, key) {
  im.resize({
    srcPath: '/Users/Kristina/Desktop/antiquep.jpg',
    dstPath: '/Users/Kristina/Desktop/tempantique.jpg',
    width: w,
    height: h
  }, function(err, stdout, stderr) {
    if (err) {
      console.error('could not process image </3');
      throw err;
    }

    if (stderr) {
      throw stderr;
    }
  });

  addHipsterOverlay(res, req, key);

};

var addHipsterOverlay = function(res, req, key) {
  var args = [process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', '/Users/Kristina/Desktop/tempantique.jpg', '-compose', 'Overlay', '-composite', process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'];
  var convert = spawn('convert', args);

  convert.stdout.pipe(fs.createWriteStream(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'));
};

// var bw_grad2 = function(res, req, key) {
//   console.log('key', key);
//   var args = ['-watermark', '90%', '-gravity', 'center', process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg' , '/Users/Kristina/Desktop/temp_bwgrad_1.jpg', '-'];
//   var composite = spawn('composite', args);

//   composite.stdout.pipe(fs.createWriteStream(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'));
// };<commit_msg>use promise in bw_grad filter<commit_after>//dependencies
var helpers = require('./helperfunctions');
var filterHelpers = require('./filterhelpers.js');
var upload = require('./upload');
var resize = require('./resize');
var fs = require('fs');
var gm = require('gm');
var im = require('imagemagick');
var uuid = require('node-uuid');
var knox = require('knox');
var spawn = require('child_process').spawn;
var Q = require('q');

module.exports = {
  //route filter based on filter param
  routeFilter: function(req, res) {
    filters[req.filter](req, res);
  }
};

var filters = {
  blur : function(req, res) {
    //default values for radius and sigma of blur filter
    var rad = req.query.r || 2;
    var sig = req.query.s || 2;

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    //read file at requested path
    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .blur(rad, sig)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  charcoal: function(req, res) {
    //default value for charcoal factor
    var factor = req.query.f || 3;

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .charcoal(factor)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  channel: function(req, res) {
    //default value for color type
    var type = req.query.t || 'red';

    //create new s3 key
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .channel(type)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  brighten: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(150, 80, 80)
    .gamma(1.2)
    .fill('#330000')
    .colorize(40)
    .contrast(+1)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  bw: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .colorspace('Gray')
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  sepia: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(115, 0, 100)
    .colorize(7, 21, 50)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  lomo: function(req, res) {
    console.log('red');
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .fill('#222b6d')
    .colorize(30)
    .modulate(90, 80, 100)
    .compose('Over')
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  gotham: function(req, res) {
    var key = uuid.v4().split('-').pop();

    gm(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg')
    .modulate(120, 10, 100)
    .fill('#222b6d')
    .colorize(20)
    .gamma(0.5)
    .contrast()
    .contrast()
    .compose('Over')
    .borderColor('black')
    .border(7,7)
    .write(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', function(err) {
      if (err) {
        throw err;
      }

      helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );
    });
  },

  //brighten

  bw_grad: function(req, res)  {
    var w;
    var h;
    var key = uuid.v4().split('-').pop();

    //obtain the dimensions of the requested image
    im.convert([process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', '-colorspace', 'gray', process.env.LOCAL_FILE_PATH + '/temp_' + req.key + '.jpg' ],
    function(err, stdout){
      if (err) {
        throw err;
      }

      im.identify(process.env.LOCAL_FILE_PATH + '/temp_' + req.key + '.jpg', function(err, features) {
        if (err) {
          console.error('could not process image </3');
          throw err;
        }

        w = features.width;
        h = features.height;

        Q.fcall(resize(req, res, w, h, key))
        .then(addBWGrad(res, req, key))
        .then(helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key ))
        .catch(function(err) {
          throw err;
        });

      });
    });
  },

  vintage: function(req, res) {
    var w;
    var h;
    var key = uuid.v4().split('-').pop();

    im.identify(process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', function(err, features) {
      if (err) {
        console.error('could not process image </3');
        throw err;
      }

      w = features.width;
      h = features.height;

      resize(req, res, w, h, key);
    });
  }
};

// var resize =  function(req, res, w, h, key) {
//   im.resize({
//     srcPath: '/Users/Kristina/Desktop/antiquefilter.jpg',
//     dstPath: '/Users/Kristina/Desktop/tempantique.jpg',
//     width: w,
//     height: h
//   }, function(err, stdout, stderr) {
//     if (err) {
//       console.error('could not process image </3');
//       throw err;
//     }

//     if (stderr) {
//       throw stderr;
//     }
//   });

//   addHipsterOverlay(res, req, key);

// };

var resize =  function(req, res, w, h, key) {
  im.resize({
    srcPath: '/Users/Kristina/Desktop/bwgrad_1.jpg',
    dstPath: '/Users/Kristina/Desktop/tempbwgrad.jpg',
    width: w,
    height: h
  }, function(err, stdout, stderr) {
    if (err) {
      console.error('could not process image </3');
      throw err;
    }

    if (stderr) {
      throw stderr;
    }
  });
};

var addHipsterOverlay = function(res, req, key) {
  var args = [process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg', '/Users/Kristina/Desktop/tempantique.jpg', '-compose', 'Overlay', '-composite', process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'];
  var convert = spawn('convert', args);

  convert.stdout.pipe(fs.createWriteStream(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'));
  helpers.helper.upload(req, res, process.env.LOCAL_FILE_PATH + '/' + key + '.jpg', 'transform', key );

};

var addBWGrad = function(res, req, key) {
  var args = ['-watermark', '90%', '-gravity', 'center', process.env.LOCAL_FILE_PATH + '/' + req.key + '.jpg' , '/Users/Kristina/Desktop/tempbwgrad.jpg', process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'];
  var composite = spawn('composite', args);

  composite.stdout.pipe(fs.createWriteStream(process.env.LOCAL_FILE_PATH + '/' + key + '.jpg'));
};<|endoftext|>


<commit_before>/* ===========================================================
 * trumbowyg.mathMl.js v1.0
 * MathML plugin for Trumbowyg
 * http://alex-d.github.com/Trumbowyg
 * ===========================================================
 * Author : loclamor
 */

/* globals MathJax */
(function($) {
    'use strict';
    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                mathml: 'Insert Formulas',
                formulas: 'Formulas',
                inline: 'Inline'
            },
            da: {
                mathml: 'Indsæt formler',
                formulas: 'Formler',
                inline: 'Inline'
            },
            fr: {
                mathml: 'Inserer une formule',
                formulas: 'Formule',
                inline: 'En ligne'
            },
            tr: {
                mathml: 'Formül Ekle',
                formulas: 'Formüller',
                inline: 'Satır içi'
            },
            zh_tw: {
                mathml: '插入方程式',
                formulas: '方程式',
                inline: '內嵌'
            },
            pt_br: {
                mathml: 'Inserir fórmulas',
                formulas: 'Fórmulas',
                inline: 'Em linha'
            },
        },
        // jshint camelcase:true

        plugins: {
            mathml: {
                init: function(trumbowyg) {
                    var btnDef = {
                        fn: function() {
                            trumbowyg.saveRange();
                            var mathMLoptions = {
                                formulas: {
                                    label: trumbowyg.lang.formulas,
                                    required: true,
                                    value: ''
                                },
                                inline: {
                                    label: trumbowyg.lang.inline,
                                    attributes: {
                                        checked: true
                                    },
                                    type: 'checkbox',
                                    required: false,
                                }
                            };

                            var mathmlCallback = function(v) {
                                var delimitor = v.inline ? '$' : '$$';
                                if (trumbowyg.currentMathNode) {
                                    $(trumbowyg.currentMathNode)
                                        .html(delimitor + ' ' + v.formulas + ' ' + delimitor)
                                        .attr('formulas', v.formulas)
                                        .attr('inline', (v.inline ? 'true' : 'false'));
                                } else {
                                    var html = '' + delimitor + ' ' + v.formulas + ' ' + delimitor + '';
                                    var node = $(html)[0];
                                    node.onclick = function() {
                                        trumbowyg.currentMathNode = this;
                                        mathMLoptions.formulas.value = $(this).attr('formulas');

                                        if ($(this).attr('inline') === 'true') {
                                            mathMLoptions.inline.attributes.checked = true;
                                        } else {
                                            delete mathMLoptions.inline.attributes.checked;
                                        }

                                        trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMLoptions, mathmlCallback);
                                    };

                                    trumbowyg.range.deleteContents();
                                    trumbowyg.range.insertNode(node);
                                }

                                trumbowyg.currentMathNode = false;
                                MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
                                return true;
                            };

                            mathMLoptions.formulas.value = trumbowyg.getRangeText();
                            mathMLoptions.inline.attributes.checked = true;
                            trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMLoptions, mathmlCallback);
                        }
                    };
                    trumbowyg.addBtnDef('mathml', btnDef);
                }
            }
        }
    });
})(jQuery);
<commit_msg>feat: add korean translation to mathml plugin<commit_after>/* ===========================================================
 * trumbowyg.mathMl.js v1.0
 * MathML plugin for Trumbowyg
 * http://alex-d.github.com/Trumbowyg
 * ===========================================================
 * Author : loclamor
 */

/* globals MathJax */
(function($) {
    'use strict';
    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                mathml: 'Insert Formulas',
                formulas: 'Formulas',
                inline: 'Inline'
            },
            da: {
                mathml: 'Indsæt formler',
                formulas: 'Formler',
                inline: 'Inline'
            },
            fr: {
                mathml: 'Inserer une formule',
                formulas: 'Formule',
                inline: 'En ligne'
            },
            tr: {
                mathml: 'Formül Ekle',
                formulas: 'Formüller',
                inline: 'Satır içi'
            },
            zh_tw: {
                mathml: '插入方程式',
                formulas: '方程式',
                inline: '內嵌'
            },
            pt_br: {
                mathml: 'Inserir fórmulas',
                formulas: 'Fórmulas',
                inline: 'Em linha'
            },
            ko: {
                mathml: '수식 넣기',
                formulas: '수식',
                inline: '글 안에 넣기'
            },
        },
        // jshint camelcase:true

        plugins: {
            mathml: {
                init: function(trumbowyg) {
                    var btnDef = {
                        fn: function() {
                            trumbowyg.saveRange();
                            var mathMLoptions = {
                                formulas: {
                                    label: trumbowyg.lang.formulas,
                                    required: true,
                                    value: ''
                                },
                                inline: {
                                    label: trumbowyg.lang.inline,
                                    attributes: {
                                        checked: true
                                    },
                                    type: 'checkbox',
                                    required: false,
                                }
                            };

                            var mathmlCallback = function(v) {
                                var delimitor = v.inline ? '$' : '$$';
                                if (trumbowyg.currentMathNode) {
                                    $(trumbowyg.currentMathNode)
                                        .html(delimitor + ' ' + v.formulas + ' ' + delimitor)
                                        .attr('formulas', v.formulas)
                                        .attr('inline', (v.inline ? 'true' : 'false'));
                                } else {
                                    var html = '' + delimitor + ' ' + v.formulas + ' ' + delimitor + '';
                                    var node = $(html)[0];
                                    node.onclick = function() {
                                        trumbowyg.currentMathNode = this;
                                        mathMLoptions.formulas.value = $(this).attr('formulas');

                                        if ($(this).attr('inline') === 'true') {
                                            mathMLoptions.inline.attributes.checked = true;
                                        } else {
                                            delete mathMLoptions.inline.attributes.checked;
                                        }

                                        trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMLoptions, mathmlCallback);
                                    };

                                    trumbowyg.range.deleteContents();
                                    trumbowyg.range.insertNode(node);
                                }

                                trumbowyg.currentMathNode = false;
                                MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
                                return true;
                            };

                            mathMLoptions.formulas.value = trumbowyg.getRangeText();
                            mathMLoptions.inline.attributes.checked = true;
                            trumbowyg.openModalInsert(trumbowyg.lang.mathml, mathMLoptions, mathmlCallback);
                        }
                    };
                    trumbowyg.addBtnDef('mathml', btnDef);
                }
            }
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   MySystem
// Copyright: ©2010 Concord Consortium
// ==========================================================================
/*globals MySystem */

// This is the function that will start your app running.  The default
// implementation will load any fixtures you have created then instantiate
// your controllers and awake the elements on your page.
//
// As you develop your application you will probably want to override this.
// See comments for some pointers on what to do next.
//

sc_require('lib/old_format_json_parser');

// MySystem.studentMode = MySystem.NOVICE_STUDENT;
MySystem.studentMode = MySystem.ADVANCED_STUDENT;

MySystem.setupStore = function setupStore(obj) {

  obj.dataSource = SC.CascadeDataSource.create({
    dataSources: ['studentStateDataSource', 'fixturesDataSource'],

    studentStateDataSource: MySystem.MergedHashDataSource.create({
      handledRecordTypes: [MySystem.Link, MySystem.Node, MySystem.Story, MySystem.StorySentence],

      // write the updated student-state data to the DOM whenever it changes
      // New: Write the updated student-state data to a variable whenever it changes.
      dataStoreDidUpdateDataHash: function () {
        var textRep = JSON.stringify(this.get('dataHash'), null, 2);
        SC.$('#my_system_state').text(textRep);
      }
    }),

    fixturesDataSource: SC.FixturesDataSource.create({
      // Patch. CascadeDataSource's commitRecords naively has each data source attempt to commit the same records.
      // (This results in an internal inconsistency error on record creation, because the fixturesDataSource tries to
      // create the same record that the studentStateDataSource has just created, and whose storeKey is therefore in
      // the wrong state -- READY instead of BUSY)
      commitRecords: function () { return YES; }
    })
  });

  // the store passes student state data to the student state data source
  obj.store = SC.Store.create({
    commitRecordsAutomatically: YES,

    setStudentStateDataHash: function (hash) {
      this.dataSource.studentStateDataSource.setDataHash(this, hash);
    },
    getStudentStateDataHash: function() {
      var dataHash = this.dataSource.studentStateDataSource.dataHash();
      return JSON.stringify(dataHash,null,2);
    }
  }).from(obj.dataSource);
};

MySystem.main = function main() {
  MySystem.setupStore(MySystem);

  // load the initial data from the DOM (see core.js)
  MySystem.updateFromDOM();

  MySystem.getPath('mainPage.mainPane').append();

  SC.ExceptionHandler = MySystem.ExceptionHandler;

  //Set the content property on the primary controller
  var nodes = MySystem.store.find(MySystem.Node);
  MySystem.nodesController.set('content', nodes);

  // Configured activity
  var activity = MySystem.store.find(MySystem.Activity, 'assign1');
  MySystem.activityController.set('content',activity);

  MySystem.energyTypes = [];
  activity.get('energyTypes').forEach( function(et) {
    MySystem.energyTypes.push({'label': et.get('label'), 'color': et.get('color'), 'isEnabled': et.get('isEnabled') } );
  });

  // User story
  var storyQuery = SC.Query.local(MySystem.StorySentence, { orderBy: 'order' });
  var storySentences = MySystem.store.find(storyQuery);
  MySystem.storySentenceController.set('content', storySentences);

  var transformations = MySystem.store.find(MySystem.Transformation);

  // MySystem.linkColorChooser = MySystem.mainPage.mainPane.childViews.objectAt(0).topLeftView.childViews.objectAt(5);
  // MySystem.linkColorChooser.set('content', 'red');
  MySystem.canvasView = MySystem.mainPage.mainPane.topView.bottomRightView.bottomRightView;
  MySystem.transformationsCanvasView = MySystem.getPath('mainPage.transformationBuilderPane').get('childViews').objectAt(0).get('childViews').objectAt(2);
  MySystem.transformationAnnotaterPane = MySystem.getPath('mainPage.transformationAnnotaterPane');

  MySystem.statechart.initStatechart();
};

function main() { MySystem.main(); }

MySystem.clearCanvas = function () {
  var i;
  var nodes = MySystem.store.find(MySystem.Node);
  for (i = 0; i < nodes.get('length'); ++i) {
      nodes.objectAt(i).destroy();
  }
  var links = MySystem.store.find(MySystem.Link);
  for (i = 0; i < links.get('length'); ++i) {
      links.objectAt(i).destroy();
  }
};

// Load canvas data for student
MySystem.loadCanvas = function () {
  MySystem.clearCanvas();
  // For now it will only load from the fixture StudentState
  var state = MySystem.store.find(MySystem.StudentState).objectAt(0);
  var json = JSON.parse(state.get('content'));
  MySystem.parseOldFormatJson(json);
};

MySystem.loadWiseConfig = function(authoredContent,latestResponse) {
  SC.run( function() {
    var activity = MySystem.Activity.fromWiseStepDef(authoredContent);
    MySystem.activityController.set('content',activity);
    MySystem.energyTypes = [];
    activity.get('energyTypes').forEach( function(et) {
      // TODO: This should be handled with an observer on the activity controller...
      MySystem.energyTypes.push({'label': et.get('label'), 'color': et.get('color'), 'isEnabled': et.get('isEnabled') } );
    });
    MySystem.updateFromDOM();
  });
};

<commit_msg>remove extra array of energy types<commit_after>// ==========================================================================
// Project:   MySystem
// Copyright: ©2010 Concord Consortium
// ==========================================================================
/*globals MySystem */

// This is the function that will start your app running.  The default
// implementation will load any fixtures you have created then instantiate
// your controllers and awake the elements on your page.
//
// As you develop your application you will probably want to override this.
// See comments for some pointers on what to do next.
//

sc_require('lib/old_format_json_parser');

// MySystem.studentMode = MySystem.NOVICE_STUDENT;
MySystem.studentMode = MySystem.ADVANCED_STUDENT;

MySystem.setupStore = function setupStore(obj) {

  obj.dataSource = SC.CascadeDataSource.create({
    dataSources: ['studentStateDataSource', 'fixturesDataSource'],

    studentStateDataSource: MySystem.MergedHashDataSource.create({
      handledRecordTypes: [MySystem.Link, MySystem.Node, MySystem.Story, MySystem.StorySentence],

      // write the updated student-state data to the DOM whenever it changes
      // New: Write the updated student-state data to a variable whenever it changes.
      dataStoreDidUpdateDataHash: function () {
        var textRep = JSON.stringify(this.get('dataHash'), null, 2);
        SC.$('#my_system_state').text(textRep);
      }
    }),

    fixturesDataSource: SC.FixturesDataSource.create({
      // Patch. CascadeDataSource's commitRecords naively has each data source attempt to commit the same records.
      // (This results in an internal inconsistency error on record creation, because the fixturesDataSource tries to
      // create the same record that the studentStateDataSource has just created, and whose storeKey is therefore in
      // the wrong state -- READY instead of BUSY)
      commitRecords: function () { return YES; }
    })
  });

  // the store passes student state data to the student state data source
  obj.store = SC.Store.create({
    commitRecordsAutomatically: YES,

    setStudentStateDataHash: function (hash) {
      this.dataSource.studentStateDataSource.setDataHash(this, hash);
    },
    getStudentStateDataHash: function() {
      var dataHash = this.dataSource.studentStateDataSource.dataHash();
      return JSON.stringify(dataHash,null,2);
    }
  }).from(obj.dataSource);
};

MySystem.main = function main() {
  MySystem.setupStore(MySystem);

  // load the initial data from the DOM (see core.js)
  MySystem.updateFromDOM();

  MySystem.getPath('mainPage.mainPane').append();

  SC.ExceptionHandler = MySystem.ExceptionHandler;

  //Set the content property on the primary controller
  var nodes = MySystem.store.find(MySystem.Node);
  MySystem.nodesController.set('content', nodes);

  // Configured activity
  var activity = MySystem.store.find(MySystem.Activity, 'assign1');
  MySystem.activityController.set('content',activity);

  // User story
  var storyQuery = SC.Query.local(MySystem.StorySentence, { orderBy: 'order' });
  var storySentences = MySystem.store.find(storyQuery);
  MySystem.storySentenceController.set('content', storySentences);

  var transformations = MySystem.store.find(MySystem.Transformation);

  // MySystem.linkColorChooser = MySystem.mainPage.mainPane.childViews.objectAt(0).topLeftView.childViews.objectAt(5);
  // MySystem.linkColorChooser.set('content', 'red');
  MySystem.canvasView = MySystem.mainPage.mainPane.topView.bottomRightView.bottomRightView;
  MySystem.transformationsCanvasView = MySystem.getPath('mainPage.transformationBuilderPane').get('childViews').objectAt(0).get('childViews').objectAt(2);
  MySystem.transformationAnnotaterPane = MySystem.getPath('mainPage.transformationAnnotaterPane');

  MySystem.statechart.initStatechart();
};

function main() { MySystem.main(); }

MySystem.clearCanvas = function () {
  var i;
  var nodes = MySystem.store.find(MySystem.Node);
  for (i = 0; i < nodes.get('length'); ++i) {
      nodes.objectAt(i).destroy();
  }
  var links = MySystem.store.find(MySystem.Link);
  for (i = 0; i < links.get('length'); ++i) {
      links.objectAt(i).destroy();
  }
};

// Load canvas data for student
MySystem.loadCanvas = function () {
  MySystem.clearCanvas();
  // For now it will only load from the fixture StudentState
  var state = MySystem.store.find(MySystem.StudentState).objectAt(0);
  var json = JSON.parse(state.get('content'));
  MySystem.parseOldFormatJson(json);
};

MySystem.loadWiseConfig = function(authoredContent,latestResponse) {
  SC.run( function() {
    var activity = MySystem.Activity.fromWiseStepDef(authoredContent);
    MySystem.activityController.set('content',activity);
    MySystem.updateFromDOM();
  });
};

<|endoftext|>


<commit_before>/**
 * Rectangle-layout manager that lays out rectangles using bitmaps at
 * resolution that may be somewhat lower than that of the coordinate
 * system for the rectangles being laid out.  `pitchX` and `pitchY`
 * are the ratios of input scale resolution to internal bitmap
 * resolution.
 */

define(
    ['dojo/_base/declare'],
    function( declare ) {
return declare( null,
{
    constructor: function( args ) {
        this.pitchX = args.pitchX || 10;
        this.pitchY = args.pitchY || 10;
        this.bitmap = [];
        this.rectangles = {};
        this.maxTop = 0;
        this.pTotalHeight = 0; // total height, in units of bitmap squares (px/pitchY)
    },

    /**
     * @returns {Number} top position for the rect
     */
    addRect: function(id, left, right, height) {
        // assumptions:
        //  - most of the rectangles being laid out will be
        //    nearly the same size
        if( this.rectangles[id] )
            return this.rectangles[id].top * this.pitchY;

        var pLeft   = Math.floor( left   / this.pitchX );
        var pRight  = Math.floor( right  / this.pitchX );
        var pHeight = Math.ceil(  height / this.pitchY );

        var midX = Math.floor((pLeft+pRight)/2);
        var rectangle = { id: id, l: pLeft, r: pRight, mX: midX, h: pHeight };

        // optimization: if this rectangle is rather deep down, and
        // does not fit at the level of the last rectangle we laid
        // out, and does not fit at the top, but does fit just below
        // it, put it just below it instead of looking for a fit
        // through the whole deep layout.  this is a very common
        // case in deep layouts. otherwise, start from the top and
        // find where rectangle fits.  speeds things up quite a bit in
        // deep layouts, and does not make the layout much worse.
        var top = this.lastTop > 40
            && this._collides( rectangle, this.lastTop )
            && this._collides( rectangle, 0 )
                ? this.lastTop+1 : 0;

        for( ; top <= this.pTotalHeight; top++ ){
            if(! this._collides(rectangle,top) )
                break;
        }
        rectangle.top = top;
        this.lastTop  = top;

        this._addRectToBitmap( rectangle );
        this.rectangles[id] = rectangle;
        //delete rectangle.mX; // don't need to store the midpoint

        this.pTotalHeight = Math.max( this.pTotalHeight||0, top+pHeight );

        return top * this.pitchY;
    },

    _collides: function( rect, top ) {
        var bitmap = this.bitmap;
        //var mY = top + rect.h/2; // Y midpoint: ( top+height  + top ) / 2

        // test the left first, then right, then middle
        var mRow = bitmap[top];
        if( mRow && ( mRow[rect.l] || mRow[rect.r] || mRow[rect.mX]) )
            return true;

        // finally, test exhaustively
        var maxY = top+rect.h;
        for( var y = top; y < maxY; y++ ) {
            var row = bitmap[y];
            if( row ) {
                if( row.allFilled )
                    return true;
                if( row.length > rect.l )
                    for( var x = rect.l; x <= rect.r; x++ )
                        if( row[x] )
                            return true;
            }
        }

        return false;
    },

    /**
     * make a subarray if it does not exist
     * @private
     */
    _autovivify: function( array, subscript ) {
        return array[subscript] ||
            (function() { var a = []; array[subscript] = a; return a; })();
    },

    _addRectToBitmap: function( rect ) {
        var bitmap = this.bitmap;
        var av = this._autovivify;
        var yEnd = rect.top+rect.h;
        if( rect.r-rect.l > 20000 ) {
            // the rect is very big in relation to the view size, just
            // pretend, for the purposes of layout, that it extends
            // infinitely.  this will cause weird layout if a user
            // scrolls manually for a very, very long time along the
            // genome at the same zoom level.  but most users will not
            // do that.
            for( var y = rect.top; y < yEnd; y++ ) {
                av(bitmap,y).allFilled = true;
            }
        }
        else {
            for( var y = rect.top; y < yEnd; y++ ) {
                var row = av(bitmap,y);
                for( var x = rect.l; x <= rect.r; x++ )
                    row[x]=true;
            }
        }
    },

    /**
     *  Given a basepair range, deletes all data dealing with the features
     */
    discardRange: function( left, right ) {
    },

    hasSeen: function( id ) {
        return !! this.rectangles[id];
    },

    cleanup: function() {
    },

    getTotalHeight: function() {
        return this.pTotalHeight * this.pitchY;
    }
}
);
});<commit_msg>remove GranularRectLayout optimization.  doesn't really help that much.<commit_after>/**
 * Rectangle-layout manager that lays out rectangles using bitmaps at
 * resolution that may be somewhat lower than that of the coordinate
 * system for the rectangles being laid out.  `pitchX` and `pitchY`
 * are the ratios of input scale resolution to internal bitmap
 * resolution.
 */

define(
    ['dojo/_base/declare'],
    function( declare ) {
return declare( null,
{
    constructor: function( args ) {
        this.pitchX = args.pitchX || 10;
        this.pitchY = args.pitchY || 10;
        this.bitmap = [];
        this.rectangles = {};
        this.maxTop = 0;
        this.pTotalHeight = 0; // total height, in units of bitmap squares (px/pitchY)
    },

    /**
     * @returns {Number} top position for the rect
     */
    addRect: function(id, left, right, height) {
        // assumptions:
        //  - most of the rectangles being laid out will be
        //    nearly the same size
        if( this.rectangles[id] )
            return this.rectangles[id].top * this.pitchY;

        var pLeft   = Math.floor( left   / this.pitchX );
        var pRight  = Math.floor( right  / this.pitchX );
        var pHeight = Math.ceil(  height / this.pitchY );

        var midX = Math.floor((pLeft+pRight)/2);
        var rectangle = { id: id, l: pLeft, r: pRight, mX: midX, h: pHeight };

        for(var top = 0; top <= this.pTotalHeight; top++ ){
            if( ! this._collides(rectangle,top) )
                break;
        }
        rectangle.top = top;

        this._addRectToBitmap( rectangle );
        this.rectangles[id] = rectangle;
        //delete rectangle.mX; // don't need to store the midpoint

        this.pTotalHeight = Math.max( this.pTotalHeight||0, top+pHeight );

        return top * this.pitchY;
    },

    _collides: function( rect, top ) {
        var bitmap = this.bitmap;
        //var mY = top + rect.h/2; // Y midpoint: ( top+height  + top ) / 2

        // test the left first, then right, then middle
        var mRow = bitmap[top];
        if( mRow && ( mRow[rect.l] || mRow[rect.r] || mRow[rect.mX]) )
            return true;

        // finally, test exhaustively
        var maxY = top+rect.h;
        for( var y = top; y < maxY; y++ ) {
            var row = bitmap[y];
            if( row ) {
                if( row.allFilled )
                    return true;
                if( row.length > rect.l )
                    for( var x = rect.l; x <= rect.r; x++ )
                        if( row[x] )
                            return true;
            }
        }

        return false;
    },

    /**
     * make a subarray if it does not exist
     * @private
     */
    _autovivify: function( array, subscript ) {
        return array[subscript] ||
            (function() { var a = []; array[subscript] = a; return a; })();
    },

    _addRectToBitmap: function( rect ) {
        var bitmap = this.bitmap;
        var av = this._autovivify;
        var yEnd = rect.top+rect.h;
        if( rect.r-rect.l > 20000 ) {
            // the rect is very big in relation to the view size, just
            // pretend, for the purposes of layout, that it extends
            // infinitely.  this will cause weird layout if a user
            // scrolls manually for a very, very long time along the
            // genome at the same zoom level.  but most users will not
            // do that.
            for( var y = rect.top; y < yEnd; y++ ) {
                av(bitmap,y).allFilled = true;
            }
        }
        else {
            for( var y = rect.top; y < yEnd; y++ ) {
                var row = av(bitmap,y);
                for( var x = rect.l; x <= rect.r; x++ )
                    row[x]=true;
            }
        }
    },

    /**
     *  Given a basepair range, deletes all data dealing with the features
     */
    discardRange: function( left, right ) {
    },

    hasSeen: function( id ) {
        return !! this.rectangles[id];
    },

    cleanup: function() {
    },

    getTotalHeight: function() {
        return this.pTotalHeight * this.pitchY;
    }
}
);
});<|endoftext|>


<commit_before>angular.module('angular-ui-flag', [])
.directive('uiFlag', function($http) {
	return {
		scope: {
			style: '=',
			width: '@?',
			height: '@?',
		},
		restrict: 'AE',
		template:
			'<svg>' +
				'<g class="ui-flag-background"></g>' +
				'<g class="ui-flag-foreground"></g>' +
				'<g class="ui-flag-feature"></g>' +
			'</svg>',
		controller: function($scope) {
			$scope.elementSections; // SVG groups of each aspect of the flag (background, foreground + feature)

			// Utility functions {{{
			$scope.splitColors = function(element) {
				var output = [[],[],[]];

				angular.element(element).find('path')
					.filter(function(key, elem) {
						var ae = angular.element(elem);
						var fill = ae.css('fill');
						var colorNo = false;

						if (ae.attr('colorNo')) { // Categorised previously
							colorNo = ae.attr('colorNo');
						} else if (fill == 'rgb(255, 0, 0)') {
							colorNo = 0;
						} else if (fill == 'rgb(0, 255, 0)') {
							colorNo = 1;
						} else if (fill == 'rgb(0, 0, 255)') {
							colorNo = 2;
						}

						if (colorNo !== false) {
							ae.attr('colorNo', colorNo);
							output[colorNo].push(ae);
						}
					});

				return output;
			};
			// }}}

			// Redrawing {{{
			// Background {{{
			$scope._lastBackground;
			$scope.redrawBackground = function() {
				if ($scope.style.background.svg == $scope._lastBackground) return $scope.styleBackground(); // No need to reload - just restyle
				$http.get($scope.style.background.svg)
					.then(function(res) {
						$scope.elementSections.background.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.background.children[0]);
						newSVG.attr({
							width: $scope.calcWidth,
							height: $scope.calcHeight,
							viewBox: '0 0 73.653713 43.963027',
						});
						if (newSVG[0].viewBox) newSVG[0].viewBox.baseVal.height = 43.963027;
						$scope.styleBackground();
						$scope._lastBackground = $scope.style.background.svg;
					})
			};

			$scope.styleBackground = function() {
				var splits = $scope.splitColors($scope.elementSections.background.children[0]);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.background.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.background.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.background.color3) });
			};
			// }}}

			// Foreground {{{
			$scope.lastForeground;
			$scope.redrawForeground = function() {
				if ($scope.style.foreground.svg == $scope._lastForeground) return $scope.styleForeground(); // No need to reload - just restyle
				$http.get($scope.style.foreground.svg)
					.then(function(res) {
						$scope.elementSections.foreground.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.foreground.children[0]);
						newSVG.attr({
							width: $scope.calcWidth,
							height: $scope.calcHeight,
						});
						$scope.styleForeground();
						$scope._lastForeground = $scope.style.foreground.svg;
					})
			};

			$scope.styleForeground = function() {
				var splits = $scope.splitColors($scope.elementSections.foreground.children[0]);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color3) });
			};
			// }}}

			// Feature {{{
			$scope._lastFeature;
			$scope._lastFeatureBackground;
			$scope.redrawFeature = function() {
				if (
					$scope.style.background.svg == $scope._lastFeatureBackground && // Background hasn't changed
					$scope.style.feature.svg == $scope._lastFeature // Feature hasn't changed
				) return $scope.styleFeature(); // No need to reload - just restyle

				$http.get($scope.style.feature.svg)
					.then(function(res) {
						var boundingElem = angular.element($scope.elementSections.background).find('#feature');
						if (!boundingElem.length) return console.warn('Cannot find #feature ID within background', $scope.style.background.svg);
						var boundingRect = boundingElem[0].getBoundingClientRect();
						console.log('BOUNDING RECT', boundingRect);

						$scope.elementSections.feature.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.feature.children[0]);
						newSVG.attr({
							left: boundingRect.left,
							top: boundingRect.top,
							width: boundingRect.width,
							height: boundingRect.height,
						});
						$scope.styleFeature();
						$scope._lastFeature = $scope.style.feature.svg;
						$scope._lastFeatureBackground = $scope.style.background.svg;
					})
			};

			$scope.styleFeature = function() {
				var splits = $scope.splitColors($scope.elementSections.feature);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.feature.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.feature.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.feature.color3) });
			};
			// }}}
			// }}}

			// Watching + trigger redrawing {{{
			// Manage background, foreground and feature changes
			$scope.$watchGroup(['style.background.svg', 'style.background.color1', 'style.background.color2', 'style.background.color3'], $scope.redrawBackground);
			$scope.$watchGroup(['style.foreground.svg', 'style.foreground.color1', 'style.foreground.color2', 'style.foreground.color3'], $scope.redrawForeground);
			$scope.$watchGroup(['style.feature.svg', 'style.background.svg', 'style.feature.color1', 'style.feature.color2', 'style.feature.color3'], $scope.redrawFeature);

			// Manage width + height changes
			$scope.$watchGroup(['width', 'height'], function() {
				$scope.calcWidth = $scope.width || 380;
				$scope.calcHeight = $scope.height || 250;
				$scope.elementSections.svg.attr({
					width: $scope.calcWidth,
					height: $scope.calcHeight,
				});
			});
			// }}}
		},
		link: function($scope, elem, attr, ctrl) {
			$scope.elementSections = {
				svg: angular.element(elem.children('svg')),
				background: elem.find('.ui-flag-background')[0],
				foreground: elem.find('.ui-flag-foreground')[0],
				feature: elem.find('.ui-flag-feature')[0],
			};
		},
	}
});
<commit_msg>Add viewBox parameter<commit_after>angular.module('angular-ui-flag', [])
.directive('uiFlag', function($http) {
	return {
		scope: {
			style: '=',
			width: '@?',
			height: '@?',
		},
		restrict: 'AE',
		template:
			'<svg viewBox="0 0 {{style.frame.width || 300}} {{style.frame.height || 200}}">' +
				'<g class="ui-flag-background"></g>' +
				'<g class="ui-flag-foreground"></g>' +
				'<g class="ui-flag-feature"></g>' +
			'</svg>',
		controller: function($scope) {
			$scope.elementSections; // SVG groups of each aspect of the flag (background, foreground + feature)

			// Utility functions {{{
			$scope.splitColors = function(element) {
				var output = [[],[],[]];

				angular.element(element).find('path')
					.filter(function(key, elem) {
						var ae = angular.element(elem);
						var fill = ae.css('fill');
						var colorNo = false;

						if (ae.attr('colorNo')) { // Categorised previously
							colorNo = ae.attr('colorNo');
						} else if (fill == 'rgb(255, 0, 0)') {
							colorNo = 0;
						} else if (fill == 'rgb(0, 255, 0)') {
							colorNo = 1;
						} else if (fill == 'rgb(0, 0, 255)') {
							colorNo = 2;
						}

						if (colorNo !== false) {
							ae.attr('colorNo', colorNo);
							output[colorNo].push(ae);
						}
					});

				return output;
			};
			// }}}

			// Redrawing {{{
			// Background {{{
			$scope._lastBackground;
			$scope.redrawBackground = function() {
				if ($scope.style.background.svg == $scope._lastBackground) return $scope.styleBackground(); // No need to reload - just restyle
				$http.get($scope.style.background.svg)
					.then(function(res) {
						$scope.elementSections.background.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.background.children[0]);
						newSVG.attr({
							width: $scope.calcWidth,
							height: $scope.calcHeight,
							viewBox: '0 0 73.653713 43.963027',
						});
						if (newSVG[0].viewBox) newSVG[0].viewBox.baseVal.height = 43.963027;
						$scope.styleBackground();
						$scope._lastBackground = $scope.style.background.svg;
					})
			};

			$scope.styleBackground = function() {
				var splits = $scope.splitColors($scope.elementSections.background.children[0]);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.background.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.background.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.background.color3) });
			};
			// }}}

			// Foreground {{{
			$scope.lastForeground;
			$scope.redrawForeground = function() {
				if ($scope.style.foreground.svg == $scope._lastForeground) return $scope.styleForeground(); // No need to reload - just restyle
				$http.get($scope.style.foreground.svg)
					.then(function(res) {
						$scope.elementSections.foreground.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.foreground.children[0]);
						newSVG.attr({
							width: $scope.calcWidth,
							height: $scope.calcHeight,
						});
						$scope.styleForeground();
						$scope._lastForeground = $scope.style.foreground.svg;
					})
			};

			$scope.styleForeground = function() {
				var splits = $scope.splitColors($scope.elementSections.foreground.children[0]);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.foreground.color3) });
			};
			// }}}

			// Feature {{{
			$scope._lastFeature;
			$scope._lastFeatureBackground;
			$scope.redrawFeature = function() {
				if (
					$scope.style.background.svg == $scope._lastFeatureBackground && // Background hasn't changed
					$scope.style.feature.svg == $scope._lastFeature // Feature hasn't changed
				) return $scope.styleFeature(); // No need to reload - just restyle

				$http.get($scope.style.feature.svg)
					.then(function(res) {
						var boundingElem = angular.element($scope.elementSections.background).find('#feature');
						if (!boundingElem.length) return console.warn('Cannot find #feature ID within background', $scope.style.background.svg);
						var boundingRect = boundingElem[0].getBoundingClientRect();
						console.log('BOUNDING RECT', boundingRect);

						$scope.elementSections.feature.innerHTML = res.data;
						var newSVG = angular.element($scope.elementSections.feature.children[0]);
						newSVG.attr({
							left: boundingRect.left,
							top: boundingRect.top,
							width: boundingRect.width,
							height: boundingRect.height,
						});
						$scope.styleFeature();
						$scope._lastFeature = $scope.style.feature.svg;
						$scope._lastFeatureBackground = $scope.style.background.svg;
					})
			};

			$scope.styleFeature = function() {
				var splits = $scope.splitColors($scope.elementSections.feature);

				splits[0].forEach(function(elem) { elem.css('fill', $scope.style.feature.color1) });
				splits[1].forEach(function(elem) { elem.css('fill', $scope.style.feature.color2) });
				splits[2].forEach(function(elem) { elem.css('fill', $scope.style.feature.color3) });
			};
			// }}}
			// }}}

			// Watching + trigger redrawing {{{
			// Manage background, foreground and feature changes
			$scope.$watchGroup(['style.background.svg', 'style.background.color1', 'style.background.color2', 'style.background.color3'], $scope.redrawBackground);
			$scope.$watchGroup(['style.foreground.svg', 'style.foreground.color1', 'style.foreground.color2', 'style.foreground.color3'], $scope.redrawForeground);
			$scope.$watchGroup(['style.feature.svg', 'style.background.svg', 'style.feature.color1', 'style.feature.color2', 'style.feature.color3'], $scope.redrawFeature);

			// Manage width + height changes
			$scope.$watchGroup(['width', 'height'], function() {
				$scope.calcWidth = $scope.width || 380;
				$scope.calcHeight = $scope.height || 250;
				$scope.elementSections.svg.attr({
					width: $scope.calcWidth,
					height: $scope.calcHeight,
				});
			});
			// }}}
		},
		link: function($scope, elem, attr, ctrl) {
			$scope.elementSections = {
				svg: angular.element(elem.children('svg')),
				background: elem.find('.ui-flag-background')[0],
				foreground: elem.find('.ui-flag-foreground')[0],
				feature: elem.find('.ui-flag-feature')[0],
			};
		},
	}
});
<|endoftext|>


<commit_before>/* ===========================================================
 * trumbowyg.upload.js v1.2
 * Upload plugin for Trumbowyg
 * http://alex-d.github.com/Trumbowyg
 * ===========================================================
 * Author : Alexandre Demode (Alex-D)
 *          Twitter : @AlexandreDemode
 *          Website : alex-d.fr
 * Mod by : Aleksandr-ru
 *          Twitter : @Aleksandr_ru
 *          Website : aleksandr.ru
 */

(function ($) {
    'use strict';

    var defaultOptions = {
        serverPath: './src/plugins/upload/trumbowyg.upload.php',
        fileFieldName: 'fileToUpload',
        data: [],
        headers: {},
        xhrFields: {},
        urlPropertyName: 'file',
        statusPropertyName: 'success',
        success: undefined,
        error: undefined
    };

    function getDeep(object, propertyParts) {
        var mainProperty = propertyParts.shift(),
            otherProperties = propertyParts;

        if (object !== null) {
            if (otherProperties.length === 0) {
                return object[mainProperty];
            }

            if (typeof object === 'object') {
                return getDeep(object[mainProperty], otherProperties);
            }
        }
        return object;
    }

    addXhrProgressEvent();

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                upload: 'Upload',
                file: 'File',
                uploadError: 'Error'
            },
            sk: {
                upload: 'Nahrať',
                file: 'Súbor',
                uploadError: 'Chyba'
            },
            fr: {
                upload: 'Envoi',
                file: 'Fichier',
                uploadError: 'Erreur'
            },
            cs: {
                upload: 'Nahrát obrázek',
                file: 'Soubor',
                uploadError: 'Chyba'
            },
            zh_cn: {
                upload: '上传',
                file: '文件',
                uploadError: '错误'
            },
            ru: {
                upload: 'Загрузка',
                file: 'Файл',
                uploadError: 'Ошибка'
            }
        },
        // jshint camelcase:true

        plugins: {
            upload: {
                init: function (trumbowyg) {
                    trumbowyg.o.plugins.upload = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.upload || {});
                    var btnDef = {
                        fn: function () {
                            trumbowyg.saveRange();

                            var file,
                                prefix = trumbowyg.o.prefix;

                            var $modal = trumbowyg.openModalInsert(
                                // Title
                                trumbowyg.lang.upload,

                                // Fields
                                {
                                    file: {
                                        type: 'file',
                                        required: true,
                                        attributes: {
                                            accept: 'image/*'
                                        }
                                    },
                                    alt: {
                                        label: 'description',
                                        value: trumbowyg.getRangeText()
                                    }
                                },

                                // Callback
                                function (values) {
                                    var data = new FormData();
                                    data.append(trumbowyg.o.plugins.upload.fileFieldName, file);

                                    trumbowyg.o.plugins.upload.data.map(function (cur) {
                                        data.append(cur.name, cur.value);
                                    });

                                    if ($('.' + prefix + 'progress', $modal).length === 0) {
                                        $('.' + prefix + 'modal-title', $modal)
                                            .after(
                                                $('<div/>', {
                                                    'class': prefix + 'progress'
                                                }).append(
                                                    $('<div/>', {
                                                        'class': prefix + 'progress-bar'
                                                    })
                                                )
                                            );
                                    }

                                    $.ajax({
                                        url: trumbowyg.o.plugins.upload.serverPath,
                                        headers: trumbowyg.o.plugins.upload.headers,
                                        xhrFields: trumbowyg.o.plugins.upload.xhrFields,
                                        type: 'POST',
                                        data: data,
                                        cache: false,
                                        dataType: 'json',
                                        processData: false,
                                        contentType: false,

                                        progressUpload: function (e) {
                                            $('.' + prefix + 'progress-bar').stop().animate({
                                                width: Math.round(e.loaded * 100 / e.total) + '%'
                                            }, 200);
                                        },

                                        success: function (data) {
                                            if (trumbowyg.o.plugins.upload.success) {
                                                trumbowyg.o.plugins.upload.success(data, trumbowyg, $modal, values);
                                            } else {
                                                if (!!getDeep(data, trumbowyg.o.plugins.upload.statusPropertyName.split('.'))) {
                                                    var url = getDeep(data, trumbowyg.o.plugins.upload.urlPropertyName.split('.'));
                                                    trumbowyg.execCmd('insertImage', url);
                                                    $('img[src="' + url + '"]:not([alt])', trumbowyg.$box).attr('alt', values.alt);
                                                    setTimeout(function () {
                                                        trumbowyg.closeModal();
                                                    }, 250);
                                                    trumbowyg.$c.trigger('tbwuploadsuccess', [trumbowyg, data, url]);
                                                } else {
                                                    trumbowyg.addErrorOnModalField(
                                                        $('input[type=file]', $modal),
                                                        trumbowyg.lang[data.message]
                                                    );
                                                    trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg, data]);
                                                }
                                            }
                                        },

                                        error: trumbowyg.o.plugins.upload.error || function () {
                                            trumbowyg.addErrorOnModalField(
                                                $('input[type=file]', $modal),
                                                trumbowyg.lang.uploadError
                                            );
                                            trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg]);
                                        }
                                    });
                                }
                            );

                            $('input[type=file]').on('change', function (e) {
                                try {
                                    // If multiple files allowed, we just get the first.
                                    file = e.target.files[0];
                                } catch (err) {
                                    // In IE8, multiple files not allowed
                                    file = e.target.value;
                                }
                            });
                        }
                    };

                    trumbowyg.addBtnDef('upload', btnDef);
                }
            }
        }
    });

    function addXhrProgressEvent() {
        if (!$.trumbowyg && !$.trumbowyg.addedXhrProgressEvent) {   // Avoid adding progress event multiple times
            var originalXhr = $.ajaxSettings.xhr;
            $.ajaxSetup({
                xhr: function () {
                    var req = originalXhr(),
                        that = this;
                    if (req && typeof req.upload === 'object' && that.progressUpload !== undefined) {
                        req.upload.addEventListener('progress', function (e) {
                            that.progressUpload(e);
                        }, false);
                    }

                    return req;
                }
            });
            $.trumbowyg.addedXhrProgressEvent = true;
        }
    }
})(jQuery);
<commit_msg>Some comments for the upload plugin<commit_after>/* ===========================================================
 * trumbowyg.upload.js v1.2
 * Upload plugin for Trumbowyg
 * http://alex-d.github.com/Trumbowyg
 * ===========================================================
 * Author : Alexandre Demode (Alex-D)
 *          Twitter : @AlexandreDemode
 *          Website : alex-d.fr
 * Mod by : Aleksandr-ru
 *          Twitter : @Aleksandr_ru
 *          Website : aleksandr.ru
 */

(function ($) {
    'use strict';

    var defaultOptions = {
        serverPath: './src/plugins/upload/trumbowyg.upload.php',
        fileFieldName: 'fileToUpload',
        data: [],                       // Additional data for ajax [{name: 'key', value: 'value'}]
        headers: {},                    // Additional headers
        xhrFields: {},                  // Additional fields
        urlPropertyName: 'file',        // How to get url from the json response (for instance 'url' for {url: ....})
        statusPropertyName: 'success',  // How to get status from the json response
        success: undefined,             // Success callback: function (data, trumbowyg, $modal, values) {}
        error: undefined                // Error callback: function () {}
    };

    function getDeep(object, propertyParts) {
        var mainProperty = propertyParts.shift(),
            otherProperties = propertyParts;

        if (object !== null) {
            if (otherProperties.length === 0) {
                return object[mainProperty];
            }

            if (typeof object === 'object') {
                return getDeep(object[mainProperty], otherProperties);
            }
        }
        return object;
    }

    addXhrProgressEvent();

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                upload: 'Upload',
                file: 'File',
                uploadError: 'Error'
            },
            sk: {
                upload: 'Nahrať',
                file: 'Súbor',
                uploadError: 'Chyba'
            },
            fr: {
                upload: 'Envoi',
                file: 'Fichier',
                uploadError: 'Erreur'
            },
            cs: {
                upload: 'Nahrát obrázek',
                file: 'Soubor',
                uploadError: 'Chyba'
            },
            zh_cn: {
                upload: '上传',
                file: '文件',
                uploadError: '错误'
            },
            ru: {
                upload: 'Загрузка',
                file: 'Файл',
                uploadError: 'Ошибка'
            }
        },
        // jshint camelcase:true

        plugins: {
            upload: {
                init: function (trumbowyg) {
                    trumbowyg.o.plugins.upload = $.extend(true, {}, defaultOptions, trumbowyg.o.plugins.upload || {});
                    var btnDef = {
                        fn: function () {
                            trumbowyg.saveRange();

                            var file,
                                prefix = trumbowyg.o.prefix;

                            var $modal = trumbowyg.openModalInsert(
                                // Title
                                trumbowyg.lang.upload,

                                // Fields
                                {
                                    file: {
                                        type: 'file',
                                        required: true,
                                        attributes: {
                                            accept: 'image/*'
                                        }
                                    },
                                    alt: {
                                        label: 'description',
                                        value: trumbowyg.getRangeText()
                                    }
                                },

                                // Callback
                                function (values) {
                                    var data = new FormData();
                                    data.append(trumbowyg.o.plugins.upload.fileFieldName, file);

                                    trumbowyg.o.plugins.upload.data.map(function (cur) {
                                        data.append(cur.name, cur.value);
                                    });

                                    if ($('.' + prefix + 'progress', $modal).length === 0) {
                                        $('.' + prefix + 'modal-title', $modal)
                                            .after(
                                                $('<div/>', {
                                                    'class': prefix + 'progress'
                                                }).append(
                                                    $('<div/>', {
                                                        'class': prefix + 'progress-bar'
                                                    })
                                                )
                                            );
                                    }

                                    $.ajax({
                                        url: trumbowyg.o.plugins.upload.serverPath,
                                        headers: trumbowyg.o.plugins.upload.headers,
                                        xhrFields: trumbowyg.o.plugins.upload.xhrFields,
                                        type: 'POST',
                                        data: data,
                                        cache: false,
                                        dataType: 'json',
                                        processData: false,
                                        contentType: false,

                                        progressUpload: function (e) {
                                            $('.' + prefix + 'progress-bar').stop().animate({
                                                width: Math.round(e.loaded * 100 / e.total) + '%'
                                            }, 200);
                                        },

                                        success: function (data) {
                                            if (trumbowyg.o.plugins.upload.success) {
                                                trumbowyg.o.plugins.upload.success(data, trumbowyg, $modal, values);
                                            } else {
                                                if (!!getDeep(data, trumbowyg.o.plugins.upload.statusPropertyName.split('.'))) {
                                                    var url = getDeep(data, trumbowyg.o.plugins.upload.urlPropertyName.split('.'));
                                                    trumbowyg.execCmd('insertImage', url);
                                                    $('img[src="' + url + '"]:not([alt])', trumbowyg.$box).attr('alt', values.alt);
                                                    setTimeout(function () {
                                                        trumbowyg.closeModal();
                                                    }, 250);
                                                    trumbowyg.$c.trigger('tbwuploadsuccess', [trumbowyg, data, url]);
                                                } else {
                                                    trumbowyg.addErrorOnModalField(
                                                        $('input[type=file]', $modal),
                                                        trumbowyg.lang[data.message]
                                                    );
                                                    trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg, data]);
                                                }
                                            }
                                        },

                                        error: trumbowyg.o.plugins.upload.error || function () {
                                            trumbowyg.addErrorOnModalField(
                                                $('input[type=file]', $modal),
                                                trumbowyg.lang.uploadError
                                            );
                                            trumbowyg.$c.trigger('tbwuploaderror', [trumbowyg]);
                                        }
                                    });
                                }
                            );

                            $('input[type=file]').on('change', function (e) {
                                try {
                                    // If multiple files allowed, we just get the first.
                                    file = e.target.files[0];
                                } catch (err) {
                                    // In IE8, multiple files not allowed
                                    file = e.target.value;
                                }
                            });
                        }
                    };

                    trumbowyg.addBtnDef('upload', btnDef);
                }
            }
        }
    });

    function addXhrProgressEvent() {
        if (!$.trumbowyg && !$.trumbowyg.addedXhrProgressEvent) {   // Avoid adding progress event multiple times
            var originalXhr = $.ajaxSettings.xhr;
            $.ajaxSetup({
                xhr: function () {
                    var req = originalXhr(),
                        that = this;
                    if (req && typeof req.upload === 'object' && that.progressUpload !== undefined) {
                        req.upload.addEventListener('progress', function (e) {
                            that.progressUpload(e);
                        }, false);
                    }

                    return req;
                }
            });
            $.trumbowyg.addedXhrProgressEvent = true;
        }
    }
})(jQuery);
<|endoftext|>