<commit_before>"use strict";

angular.module('arethusa-core').service('state', function(configurator, history) {
  var conf = configurator.configurationFor('state');
  var tokenRetriever = configurator.getService(conf.retriever);

  var temp_tokens;
  tokenRetriever.getData(function(res) {
    temp_tokens = res;
  });
  this.tokens = temp_tokens;

  this.asString = function(id) {
    return this.tokens[id].string;
  };

  this.selectedTokens = {}; // ids will be inserted here

  this.isSelected = function(id) {
    return id in this.selectedTokens;
  };

  this.currentTokens = function() {
    var res = [];
    var that = this;
    angular.forEach(that.selectedTokens, function(val, id) {
      var token = that.tokens[id];
      if (token) {
        res.push(token);
      }
    });
    return res;
  };

  this.currentTokensAsStringList = function() {
    return $.map(
      this.currentTokens(),
      function(el, i) {
        return el.string;
      }
    ).join(', ');
  };

  // type should be either 'click' or 'hover'
  this.selectToken = function(id, type) {
    if (this.isSelectable(this.selectionType(id), type)) {
      this.selectedTokens[id] = type;
    }
  };

  this.selectionType = function(id) {
    return this.selectedTokens[id];
  };

  this.isSelectable = function(oldVal, newVal) {
    // if an element was hovered, we only select it when another
    // selection type is present (such as 'click'), if there was
    // no selection at all (oldVal === undefined), we select too
    return (oldVal === 'hover' && newVal !== 'hover') || (! oldVal);
  };

  this.deselectToken = function(id, type) {
    // only deselect when the old selection type is the same as
    // the argument, i.e. a hover selection can only deselect a
    // hover selection, but not a click selection
    if (this.selectionType(id) === type) {
      delete this.selectedTokens[id];
    }
  };

  this.toggleSelection = function(id, type) {
    // only deselect when the selectionType is the same.
    // a hovered selection can still be selected by click.
    if (this.isSelected(id) && this.selectionType(id) == type) {
      this.deselectToken(id, type);
    } else {
      this.selectToken(id, type);
    }
  };

  this.deselectAll = function() {
    for (var el in this.selectedTokens) delete this.selectedTokens[el];
  };

  this.selectSurroundingToken = function(direction) {
    // take the first current selection
    var firstId = Object.keys(this.selectedTokens)[0];
    var allIds  = Object.keys(this.tokens);
    var index = allIds.indexOf(firstId);

    // select newId - make a roundtrip if we reached the bounds of the array
    var newId;
    switch(direction) {
      case "next":
        newId = allIds[index + 1] || allIds[0]; break;
      case "prev":
        newId = allIds[index - 1] || allIds[allIds.length - 1]; break;
    }

    // deselect all previously selected tokens
    this.deselectAll();
    // and select the new one
    this.selectToken(newId, 'click');
  };

  this.selectNextToken = function() { this.selectSurroundingToken('next'); };
  this.selectPrevToken = function() { this.selectSurroundingToken('prev'); };

  // Listeners can be internal (angular-implementation) or external (everything
  // else). The future might bring a further distinction between different
  // of events listeners listen to - we'll see.
  this.listeners = [];
  this.externalListeners= [];

  this.registerListener = function(listener) {
    if (listener.external) {
      this.externalListeners.push(listener);
    } else {
      this.listeners.push(listener);
    }
  };

  this.fireEvent = function(target, property, oldVal, newVal) {
    var event = { target: target, property: property, oldVal: oldVal, newVal: newVal };
    event.time = new Date();
    this.notifyListeners(event);
  };

  this.notifyListeners = function(event) {
    this.notifyAngularListeners(event);
    this.notifyExternalListeners(event);
  };

  this.notifyAngularListeners = function(event) {
    angular.forEach(this.listeners, function(obj, i) {
      obj.catchEvent(event);
    });
  };

  this.notifyExternalListeners = function(event) {
    // tbd
  };

  this.setState = function(id, category, val) {
    var token = this.tokens[id];
    var oldVal = token[category];
    this.fireEvent(token, category, oldVal, val);
    token[category] = val;
  };

  this.unsetState = function(id, category) {
    var token = this.tokens[id];
    var oldVal = token[category];
    this.fireEvent(token, category, oldVal,  null);
    delete token[category];
  };
});
<commit_msg>No need to inject history into state anymore<commit_after>"use strict";

angular.module('arethusa-core').service('state', function(configurator) {
  var conf = configurator.configurationFor('state');
  var tokenRetriever = configurator.getService(conf.retriever);

  var temp_tokens;
  tokenRetriever.getData(function(res) {
    temp_tokens = res;
  });
  this.tokens = temp_tokens;

  this.asString = function(id) {
    return this.tokens[id].string;
  };

  this.selectedTokens = {}; // ids will be inserted here

  this.isSelected = function(id) {
    return id in this.selectedTokens;
  };

  this.currentTokens = function() {
    var res = [];
    var that = this;
    angular.forEach(that.selectedTokens, function(val, id) {
      var token = that.tokens[id];
      if (token) {
        res.push(token);
      }
    });
    return res;
  };

  this.currentTokensAsStringList = function() {
    return $.map(
      this.currentTokens(),
      function(el, i) {
        return el.string;
      }
    ).join(', ');
  };

  // type should be either 'click' or 'hover'
  this.selectToken = function(id, type) {
    if (this.isSelectable(this.selectionType(id), type)) {
      this.selectedTokens[id] = type;
    }
  };

  this.selectionType = function(id) {
    return this.selectedTokens[id];
  };

  this.isSelectable = function(oldVal, newVal) {
    // if an element was hovered, we only select it when another
    // selection type is present (such as 'click'), if there was
    // no selection at all (oldVal === undefined), we select too
    return (oldVal === 'hover' && newVal !== 'hover') || (! oldVal);
  };

  this.deselectToken = function(id, type) {
    // only deselect when the old selection type is the same as
    // the argument, i.e. a hover selection can only deselect a
    // hover selection, but not a click selection
    if (this.selectionType(id) === type) {
      delete this.selectedTokens[id];
    }
  };

  this.toggleSelection = function(id, type) {
    // only deselect when the selectionType is the same.
    // a hovered selection can still be selected by click.
    if (this.isSelected(id) && this.selectionType(id) == type) {
      this.deselectToken(id, type);
    } else {
      this.selectToken(id, type);
    }
  };

  this.deselectAll = function() {
    for (var el in this.selectedTokens) delete this.selectedTokens[el];
  };

  this.selectSurroundingToken = function(direction) {
    // take the first current selection
    var firstId = Object.keys(this.selectedTokens)[0];
    var allIds  = Object.keys(this.tokens);
    var index = allIds.indexOf(firstId);

    // select newId - make a roundtrip if we reached the bounds of the array
    var newId;
    switch(direction) {
      case "next":
        newId = allIds[index + 1] || allIds[0]; break;
      case "prev":
        newId = allIds[index - 1] || allIds[allIds.length - 1]; break;
    }

    // deselect all previously selected tokens
    this.deselectAll();
    // and select the new one
    this.selectToken(newId, 'click');
  };

  this.selectNextToken = function() { this.selectSurroundingToken('next'); };
  this.selectPrevToken = function() { this.selectSurroundingToken('prev'); };

  // Listeners can be internal (angular-implementation) or external (everything
  // else). The future might bring a further distinction between different
  // of events listeners listen to - we'll see.
  this.listeners = [];
  this.externalListeners= [];

  this.registerListener = function(listener) {
    if (listener.external) {
      this.externalListeners.push(listener);
    } else {
      this.listeners.push(listener);
    }
  };

  this.fireEvent = function(target, property, oldVal, newVal) {
    var event = { target: target, property: property, oldVal: oldVal, newVal: newVal };
    event.time = new Date();
    this.notifyListeners(event);
  };

  this.notifyListeners = function(event) {
    this.notifyAngularListeners(event);
    this.notifyExternalListeners(event);
  };

  this.notifyAngularListeners = function(event) {
    angular.forEach(this.listeners, function(obj, i) {
      obj.catchEvent(event);
    });
  };

  this.notifyExternalListeners = function(event) {
    // tbd
  };

  this.setState = function(id, category, val) {
    var token = this.tokens[id];
    var oldVal = token[category];
    this.fireEvent(token, category, oldVal, val);
    token[category] = val;
  };

  this.unsetState = function(id, category) {
    var token = this.tokens[id];
    var oldVal = token[category];
    this.fireEvent(token, category, oldVal,  null);
    delete token[category];
  };
});
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const structureConfig = require('./structure.config.js');

const { paths } = structureConfig;
const { filenames } = structureConfig;

const config = {
  mode: 'development',
  entry: {
    app: [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client',
      path.join(paths.source, filenames.indexJS),
    ],
  },
  resolve: {
    extensions: ['.css', '.js', '.jsx'],
    modules: [paths.source, paths.nodeModules],
  },
  context: paths.source,
  output: {
    filename: filenames.dev.JS,
    path: paths.dev,
    publicPath: '/dev/',
  },
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              camelCase: true,
              localIdentName: '[name]__[local]___[hash:base64:5]',
              modules: true,
            },
          },
        ],
      },
      {
        test: /\.jsx?$/,
        use: ['babel-loader'],
        include: paths.source,
      },
      {
        test: /\.(eot|jpe?g|png|svg|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
  ],
};

module.exports = config;
<commit_msg>Add blank line<commit_after>const path = require('path');
const webpack = require('webpack');

const structureConfig = require('./structure.config.js');

const { paths } = structureConfig;
const { filenames } = structureConfig;

const config = {
  mode: 'development',
  entry: {
    app: [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client',
      path.join(paths.source, filenames.indexJS),
    ],
  },
  resolve: {
    extensions: ['.css', '.js', '.jsx'],
    modules: [paths.source, paths.nodeModules],
  },
  context: paths.source,
  output: {
    filename: filenames.dev.JS,
    path: paths.dev,
    publicPath: '/dev/',
  },
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              camelCase: true,
              localIdentName: '[name]__[local]___[hash:base64:5]',
              modules: true,
            },
          },
        ],
      },
      {
        test: /\.jsx?$/,
        use: ['babel-loader'],
        include: paths.source,
      },
      {
        test: /\.(eot|jpe?g|png|svg|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
  ],
};

module.exports = config;
<|endoftext|>


<commit_before>var express = require('express'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
port = process.env.PORT || 8080,
route = require('./app/routes/route.js'),
colors = require('colors'),
app = express(),
passport = require('passport'),
cookieParser = require('cookie-parser'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
session = require('express-session'),
Sequelize = require('sequelize'),
fileUpload = require('express-fileupload'),
special = require('./app/model/special'),
fs = require('fs');

module.exports.DEVELOPMENT_USE_DATABASE = false;

app.set('view engine', 'jade');
app.set('views', './app/views');

app.use(bodyParser.json());
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: false}));
app.use(fileUpload());

if (port == 80 || module.exports.DEVELOPMENT_USE_DATABASE) {
  var sequelize = new Sequelize(process.env.DATABASE_URL,
    {logging: false, ssl: true, dialectOptions: {ssl: true}});
  var User = sequelize.import(__dirname + '/app/model/User.js');

  var SequelizeStore = require('connect-session-sequelize')(session.Store);
  var sessionStore = new SequelizeStore({
    db: sequelize,
    checkExpirationInterval: 15 * 60 * 1000,
    expiration: 7 * 24 * 60 * 60 * 1000
  });

  require(__dirname + '/config/passport.js')(passport, GoogleStrategy, User);

  app.use(session({
    store: sessionStore,
    secret: process.env.SESSION_KEY || 'this is a development secret key',
    resave: false,
    saveUninitialized: true,
  }));
  sessionStore.sync();
  app.use(passport.initialize());
  app.use(passport.session());
}

app.use(methodOverride('X-HTTP-Method-Override'));

app.locals.production = (port == process.env.PORT);

app.use('/', express.static(__dirname + '/public/'));
app.use('/public', express.static(__dirname + '/bower_components/'));
app.use('/fonts', express.static(__dirname + '/bower_components/bootstrap/fonts/'));
app.use('/', route);
app.use('/', require('./app/routes/googleauth.js'));

app.use('/special', express.static(__dirname + '/uploads/'));
fs.readdir('./uploads', function(err, files) {
  files.forEach(function(file) {
    special.special.push(parseInt(file.split('.')[0]));
  });
});

app.listen(port, function() {
  console.log(colors.rainbow('Listening on port ' +  port));
});
<commit_msg>Fix issue if folder does not exist<commit_after>var express = require('express'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
port = process.env.PORT || 8080,
route = require('./app/routes/route.js'),
colors = require('colors'),
app = express(),
passport = require('passport'),
cookieParser = require('cookie-parser'),
GoogleStrategy = require('passport-google-oauth').OAuth2Strategy,
session = require('express-session'),
Sequelize = require('sequelize'),
fileUpload = require('express-fileupload'),
special = require('./app/model/special'),
fs = require('fs');

module.exports.DEVELOPMENT_USE_DATABASE = false;

app.set('view engine', 'jade');
app.set('views', './app/views');

app.use(bodyParser.json());
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended: false}));
app.use(fileUpload());

if (port == 80 || module.exports.DEVELOPMENT_USE_DATABASE) {
  var sequelize = new Sequelize(process.env.DATABASE_URL,
    {logging: false, ssl: true, dialectOptions: {ssl: true}});
  var User = sequelize.import(__dirname + '/app/model/User.js');

  var SequelizeStore = require('connect-session-sequelize')(session.Store);
  var sessionStore = new SequelizeStore({
    db: sequelize,
    checkExpirationInterval: 15 * 60 * 1000,
    expiration: 7 * 24 * 60 * 60 * 1000
  });

  require(__dirname + '/config/passport.js')(passport, GoogleStrategy, User);

  app.use(session({
    store: sessionStore,
    secret: process.env.SESSION_KEY || 'this is a development secret key',
    resave: false,
    saveUninitialized: true,
  }));
  sessionStore.sync();
  app.use(passport.initialize());
  app.use(passport.session());
}

app.use(methodOverride('X-HTTP-Method-Override'));

app.locals.production = (port == process.env.PORT);

app.use('/', express.static(__dirname + '/public/'));
app.use('/public', express.static(__dirname + '/bower_components/'));
app.use('/fonts', express.static(__dirname + '/bower_components/bootstrap/fonts/'));
app.use('/', route);
app.use('/', require('./app/routes/googleauth.js'));

app.use('/special', express.static(__dirname + '/uploads/'));
fs.readdir('./uploads', function(err, files) {
  if (files) {
    files.forEach(function(file) {
      special.special.push(parseInt(file.split('.')[0]));
    });
  }
});

app.listen(port, function() {
  console.log(colors.rainbow('Listening on port ' +  port));
});
<|endoftext|>


<commit_before>define([
  'jquery',
  'backbone'
], function($, Backbone) {

  'use strict';

  const topics = {
    'report-a-bug-or-error-on-gfw': {
      name: 'Report a bug or error on GFW',
      placeholder: 'Explain the bug or error and tell us where on the website you encountered it. What browser (e.g., Chrome version 50.0.2661.94 m) and operating system (e.g., Windows 8.1) do you use?',
    },
    'provide-feedback': {
      name: 'Provide feedback',
      placeholder: 'Tell us about your experience with GFW! Examples: How can we improve GFW? Why did you visit GFW? How do you use GFW? If and how is the information provided by GFW useful for your work? Are there any additional features and/or data that would be useful?  Was anything confusing or difficult to use?  Etc...',
    },
    'media-request': {
      name: 'Media request',
      placeholder: 'How can we help you?',
    },
    'data-related-inquiry': {
      name: 'Data-related inquiry or suggestion',
      placeholder: 'How can we help you?',
    },
    'gfw-commodities-inquiry': {
      name: 'GFW Commodities inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-fires-inquiry': {
      name: 'GFW Fires inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-climate-inquiry': {
      name: 'GFW Climate inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-water-inquiry': {
      name: 'GFW Water inquiry',
      placeholder: 'How can we help you?',
    },
    'general-inquiry': {
      name: 'General inquiry',
      placeholder: 'How can we help you?',
    },
  }

  const constraints = {
    'contact-email': {
      presence: true,
      email: true
    },
    'contact-topic': {
      presence: true
    },
    'contact-message': {
      presence: true
    }
  };

  var ContacUsView = Backbone.View.extend({

    el: '#contact_us',

    events: {
      'click .js-btn-submit': 'actionSubmit',
      'change input, textarea, select': 'changeInput',
    },

    initialize: function() {
      this.$spinner = this.$el.find('.m-spinner');
      this.$form = this.$el.find('#contact-form');
      this.$step = this.$el.find('.step');
      this.$stepBtn = this.$el.find('.step-btn');
      this.$contactMessage = this.$el.find('#contact-message');
    },

    actionSubmit(e) {
      e && e.preventDefault();
      (this.validate(e)) ? this.sendForm() : this.updateForm();
    },

    // Send the data to the API
    sendForm() {
      // Production send request
      // Send request
      this.$spinner.addClass('-start');
      var xhr = new XMLHttpRequest();

      xhr.open('POST', window.gfw.config.GFW_API_HOST + '/emails');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');

      xhr.onload = function() {
        if (xhr.status === 200 || xhr.status === 201) {
          this.changeStep('success');
          this.resetForm();
          this.$spinner.removeClass('-start');
        } else {
          this.changeStep('error');
          this.$spinner.removeClass('-start');
        }
      }.bind(this);

      xhr.onerror = () => {
        this.changeStep('error');
        this.$spinner.removeClass('-start');
      }

      xhr.send(JSON.stringify(this.serialize(this.$form[0])));

      // // Develop Send request
      // // Comment this code if this is going to pro
      // if (true) {
      //   this.changeStep('success');
      //   this.$spinner.removeClass('-start');
      // } else {
      //   this.changeStep('error');
      //   this.$spinner.removeClass('-start');
      // }
    },

    updateForm() {
      this.$form.find('input, textarea, select').removeClass('-error');
      this.$form.find('label').removeClass('-error');
      for (var key in this.errors) {
        var $input = this.$form.find('#'+key);
        var $label = this.$form.find('label[for='+key+']');
        $input.addClass('-error');
        $label.addClass('-error');
      }
    },

    resetForm() {
      this.$form.find('input, textarea, select').val(null);
    },

    serialize(form) {
    	if (!form || form.nodeName !== "FORM") {
    		return;
    	}
    	let obj = {};
    	for (let i = form.elements.length - 1; i >= 0; i = i - 1) {
    		if (form.elements[i].name === "") {
    			continue;
    		}
    		switch (form.elements[i].nodeName) {
    		case 'INPUT':
    			switch (form.elements[i].type) {
    			case 'text':
    			case 'email':
    			case 'hidden':
    			case 'password':
    			case 'button':
    			case 'reset':
    			case 'submit':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'checkbox':
    			case 'radio':
            if (form.elements[i].checked) {
              obj[form.elements[i].name] = form.elements[i].value;
            } else if (!obj[form.elements[i].name]) {
              obj[form.elements[i].name] = false;
            }
    				break;
    			case 'file':
    				break;
    			}
    			break;
    		case 'TEXTAREA':
    			obj[form.elements[i].name] = form.elements[i].value;
    			break;
    		case 'SELECT':
    			switch (form.elements[i].type) {
    			case 'select-one':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'select-multiple':
    				for (let j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
    					if (form.elements[i].options[j].selected) {
    						obj[form.elements[i].name] = form.elements[i].options[j].value;
    					}
    				}
    				break;
    			}
    			break;
    		case 'BUTTON':
    			switch (form.elements[i].type) {
    			case 'reset':
    			case 'submit':
    			case 'button':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			}
    			break;
    		}
    	}
    	return obj;
    },

    validate(e) {
      e && e.preventDefault();
      let attributes = this.serialize(this.$form[0]);

      // Validate form, if is valid the response will be undefined
      this.errors = validate(attributes, constraints);
      return ! !!this.errors;
    },

    validateInput(name, value) {
      let errors = validate.single(value, constraints[name]);
      if (!!errors && this.errors) {
        this.errors[name] = errors[0];
      } else {
        this.errors && this.errors[name] && delete this.errors[name];
      }
    },

    changeInput(e) {
      e && e.preventDefault();
      this.validateInput(e.currentTarget.name, e.currentTarget.value);
      this.updateForm();
    },

    changeStep(step) {
      this.$step.removeClass('-active');
      this.$stepBtn.removeClass('-active');

      // Set actives
      this.$el.find('.step[data-step="'+step+'"]').addClass('-active');
      this.$el.find('.step-btn[data-step="'+step+'"]').addClass('-active');
    },

    changeTopic(e) {
      var topic = e.currentTarget.value;
      if (!!topic) {
        var placeholder = topics[topic]['placeholder'];
        this.$contactMessage.attr('placeholder', placeholder);
      }
    }

  });

  return ContacUsView;
});
<commit_msg>Add event on topic change<commit_after>define([
  'jquery',
  'backbone'
], function($, Backbone) {

  'use strict';

  const topics = {
    'report-a-bug-or-error-on-gfw': {
      name: 'Report a bug or error on GFW',
      placeholder: 'Explain the bug or error and tell us where on the website you encountered it. What browser (e.g., Chrome version 50.0.2661.94 m) and operating system (e.g., Windows 8.1) do you use?',
    },
    'provide-feedback': {
      name: 'Provide feedback',
      placeholder: 'Tell us about your experience with GFW! Examples: How can we improve GFW? Why did you visit GFW? How do you use GFW? If and how is the information provided by GFW useful for your work? Are there any additional features and/or data that would be useful?  Was anything confusing or difficult to use?  Etc...',
    },
    'media-request': {
      name: 'Media request',
      placeholder: 'How can we help you?',
    },
    'data-related-inquiry': {
      name: 'Data-related inquiry or suggestion',
      placeholder: 'How can we help you?',
    },
    'gfw-commodities-inquiry': {
      name: 'GFW Commodities inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-fires-inquiry': {
      name: 'GFW Fires inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-climate-inquiry': {
      name: 'GFW Climate inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-water-inquiry': {
      name: 'GFW Water inquiry',
      placeholder: 'How can we help you?',
    },
    'general-inquiry': {
      name: 'General inquiry',
      placeholder: 'How can we help you?',
    },
  }

  const constraints = {
    'contact-email': {
      presence: true,
      email: true
    },
    'contact-topic': {
      presence: true
    },
    'contact-message': {
      presence: true
    }
  };

  var ContacUsView = Backbone.View.extend({

    el: '#contact_us',

    events: {
      'click .js-btn-submit': 'actionSubmit',
      'change input, textarea, select': 'changeInput',
      'change #contact-topic': 'changeTopic'
    },

    initialize: function() {
      this.$spinner = this.$el.find('.m-spinner');
      this.$form = this.$el.find('#contact-form');
      this.$step = this.$el.find('.step');
      this.$stepBtn = this.$el.find('.step-btn');
      this.$contactMessage = this.$el.find('#contact-message');
    },

    actionSubmit(e) {
      e && e.preventDefault();
      (this.validate(e)) ? this.sendForm() : this.updateForm();
    },

    // Send the data to the API
    sendForm() {
      // Production send request
      // Send request
      this.$spinner.addClass('-start');
      var xhr = new XMLHttpRequest();

      xhr.open('POST', window.gfw.config.GFW_API_HOST + '/emails');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');

      xhr.onload = function() {
        if (xhr.status === 200 || xhr.status === 201) {
          this.changeStep('success');
          this.resetForm();
          this.$spinner.removeClass('-start');
        } else {
          this.changeStep('error');
          this.$spinner.removeClass('-start');
        }
      }.bind(this);

      xhr.onerror = () => {
        this.changeStep('error');
        this.$spinner.removeClass('-start');
      }

      xhr.send(JSON.stringify(this.serialize(this.$form[0])));

      // // Develop Send request
      // // Comment this code if this is going to pro
      // if (true) {
      //   this.changeStep('success');
      //   this.$spinner.removeClass('-start');
      // } else {
      //   this.changeStep('error');
      //   this.$spinner.removeClass('-start');
      // }
    },

    updateForm() {
      this.$form.find('input, textarea, select').removeClass('-error');
      this.$form.find('label').removeClass('-error');
      for (var key in this.errors) {
        var $input = this.$form.find('#'+key);
        var $label = this.$form.find('label[for='+key+']');
        $input.addClass('-error');
        $label.addClass('-error');
      }
    },

    resetForm() {
      this.$form.find('input, textarea, select').val(null);
    },

    serialize(form) {
    	if (!form || form.nodeName !== "FORM") {
    		return;
    	}
    	let obj = {};
    	for (let i = form.elements.length - 1; i >= 0; i = i - 1) {
    		if (form.elements[i].name === "") {
    			continue;
    		}
    		switch (form.elements[i].nodeName) {
    		case 'INPUT':
    			switch (form.elements[i].type) {
    			case 'text':
    			case 'email':
    			case 'hidden':
    			case 'password':
    			case 'button':
    			case 'reset':
    			case 'submit':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'checkbox':
    			case 'radio':
            if (form.elements[i].checked) {
              obj[form.elements[i].name] = form.elements[i].value;
            } else if (!obj[form.elements[i].name]) {
              obj[form.elements[i].name] = false;
            }
    				break;
    			case 'file':
    				break;
    			}
    			break;
    		case 'TEXTAREA':
    			obj[form.elements[i].name] = form.elements[i].value;
    			break;
    		case 'SELECT':
    			switch (form.elements[i].type) {
    			case 'select-one':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'select-multiple':
    				for (let j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
    					if (form.elements[i].options[j].selected) {
    						obj[form.elements[i].name] = form.elements[i].options[j].value;
    					}
    				}
    				break;
    			}
    			break;
    		case 'BUTTON':
    			switch (form.elements[i].type) {
    			case 'reset':
    			case 'submit':
    			case 'button':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			}
    			break;
    		}
    	}
    	return obj;
    },

    validate(e) {
      e && e.preventDefault();
      let attributes = this.serialize(this.$form[0]);

      // Validate form, if is valid the response will be undefined
      this.errors = validate(attributes, constraints);
      return ! !!this.errors;
    },

    validateInput(name, value) {
      let errors = validate.single(value, constraints[name]);
      if (!!errors && this.errors) {
        this.errors[name] = errors[0];
      } else {
        this.errors && this.errors[name] && delete this.errors[name];
      }
    },

    changeInput(e) {
      e && e.preventDefault();
      this.validateInput(e.currentTarget.name, e.currentTarget.value);
      this.updateForm();
    },

    changeStep(step) {
      this.$step.removeClass('-active');
      this.$stepBtn.removeClass('-active');

      // Set actives
      this.$el.find('.step[data-step="'+step+'"]').addClass('-active');
      this.$el.find('.step-btn[data-step="'+step+'"]').addClass('-active');
    },

    changeTopic(e) {
      var topic = e.currentTarget.value;
      if (!!topic) {
        var placeholder = topics[topic]['placeholder'];
        this.$contactMessage.attr('placeholder', placeholder);
      }
    }

  });

  return ContacUsView;
});
<|endoftext|>


<commit_before>/* eslint-env node */

'use strict';

var Merge = require('webpack-merge');
var path = require('path');
var webpack = require('webpack');

var commonConfig = require('./webpack.common.config.js');

module.exports = Merge.smart(commonConfig, {
    output: {
        filename: '[name].js'
    },
    devtool: 'source-map',
    plugins: [
        new webpack.LoaderOptionsPlugin({
            debug: true
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
        })
    ],
    module: {
        rules: [
            {
                test: /(.scss|.css)$/,
                include: [
                    /studio-frontend/,
                    /paragon/,
                    /font-awesome/
                ],
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                            modules: true,
                            localIdentName: '[path][name]__[local]--[hash:base64:5]'
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            data: '$base-rem-size: 0.625; @import "paragon-reset";',
                            includePaths: [
                                path.join(__dirname, './node_modules/@edx/paragon/src/utils'),
                                path.join(__dirname, './node_modules/')
                            ],
                            sourceMap: true
                        }
                    }
                ]
            }
        ]
    },
    watchOptions: {
        ignored: [/node_modules/, /\.git/]
    }
});
<commit_msg>Remove hash & path on dev webpack css module names<commit_after>/* eslint-env node */

'use strict';

var Merge = require('webpack-merge');
var path = require('path');
var webpack = require('webpack');

var commonConfig = require('./webpack.common.config.js');

module.exports = Merge.smart(commonConfig, {
    output: {
        filename: '[name].js'
    },
    devtool: 'source-map',
    plugins: [
        new webpack.LoaderOptionsPlugin({
            debug: true
        }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
        })
    ],
    module: {
        rules: [
            {
                test: /(.scss|.css)$/,
                include: [
                    /studio-frontend/,
                    /paragon/,
                    /font-awesome/
                ],
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: true,
                            modules: true,
                            localIdentName: '[name]__[local]'
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            data: '$base-rem-size: 0.625; @import "paragon-reset";',
                            includePaths: [
                                path.join(__dirname, './node_modules/@edx/paragon/src/utils'),
                                path.join(__dirname, './node_modules/')
                            ],
                            sourceMap: true
                        }
                    }
                ]
            }
        ]
    },
    watchOptions: {
        ignored: [/node_modules/, /\.git/]
    }
});
<|endoftext|>


<commit_before>define([
  'jquery',
  'backbone'
], function($, Backbone) {

  'use strict';

  const topics = {
    'report-a-bug-or-error-on-gfw': {
      name: 'Report a bug or error on GFW',
      placeholder: 'Explain the bug or error and tell us where on the website you encountered it. What browser (e.g., Chrome version 50.0.2661.94 m) and operating system (e.g., Windows 8.1) do you use?',
    },
    'provide-feedback': {
      name: 'Provide feedback',
      placeholder: 'Tell us about your experience with GFW! Examples: How can we improve GFW? Why did you visit GFW? How do you use GFW? If and how is the information provided by GFW useful for your work? Are there any additional features and/or data that would be useful?  Was anything confusing or difficult to use?  Etc...',
    },
    'media-request': {
      name: 'Media request',
      placeholder: 'How can we help you?',
    },
    'data-related-inquiry': {
      name: 'Data-related inquiry or suggestion',
      placeholder: 'How can we help you?',
    },
    'gfw-commodities-inquiry': {
      name: 'GFW Commodities inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-fires-inquiry': {
      name: 'GFW Fires inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-climate-inquiry': {
      name: 'GFW Climate inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-water-inquiry': {
      name: 'GFW Water inquiry',
      placeholder: 'How can we help you?',
    },
    'general-inquiry': {
      name: 'General inquiry',
      placeholder: 'How can we help you?',
    },
  }

  const constraints = {
    'contact-email': {
      presence: true,
      email: true
    },
    'contact-topic': {
      presence: true
    },
    'contact-message': {
      presence: true
    }
  };

  var ContacUsView = Backbone.View.extend({

    el: '#contact_us',

    events: {
      'click .js-btn-submit': 'actionSubmit',
      'change input, textarea, select': 'changeInput',
      'change #contact-topic': 'changeTopic'
    },

    initialize: function() {
      this.$spinner = this.$el.find('.m-spinner');
      this.$form = this.$el.find('#contact-form');
      this.$step = this.$el.find('.step');
      this.$stepBtn = this.$el.find('.step-btn');
      this.$contactMessage = this.$el.find('#contact-message');
    },

    actionSubmit(e) {
      e && e.preventDefault();
      (this.validate(e)) ? this.sendForm() : this.updateForm();
    },

    // Send the data to the API
    sendForm() {
      // Production send request
      // Send request
      this.$spinner.addClass('-start');
      var xhr = new XMLHttpRequest();

      xhr.open('POST', window.gfw.config.GFW_API_HOST + '/emails');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');

      xhr.onload = function() {
        if (xhr.status === 200 || xhr.status === 201) {
          this.changeStep('success');
          this.resetForm();
          this.$spinner.removeClass('-start');
        } else {
          this.changeStep('error');
          this.$spinner.removeClass('-start');
        }
      }.bind(this);

      xhr.onerror = () => {
        this.changeStep('error');
        this.$spinner.removeClass('-start');
      }

      xhr.send(JSON.stringify(this.serialize(this.$form[0])));

      // // Develop Send request
      // // Comment this code if this is going to pro
      // if (true) {
      //   this.changeStep('success');
      //   this.$spinner.removeClass('-start');
      // } else {
      //   this.changeStep('error');
      //   this.$spinner.removeClass('-start');
      // }
    },

    updateForm() {
      this.$form.find('input, textarea, select').removeClass('-error');
      this.$form.find('label').removeClass('-error');
      for (var key in this.errors) {
        var $input = this.$form.find('#'+key);
        var $label = this.$form.find('label[for='+key+']');
        $input.addClass('-error');
        $label.addClass('-error');
      }
    },

    resetForm() {
      this.$form.find('input, textarea, select').val(null);
    },

    serialize(form) {
    	if (!form || form.nodeName !== "FORM") {
    		return;
    	}
    	let obj = {};
    	for (let i = form.elements.length - 1; i >= 0; i = i - 1) {
    		if (form.elements[i].name === "") {
    			continue;
    		}
    		switch (form.elements[i].nodeName) {
    		case 'INPUT':
    			switch (form.elements[i].type) {
    			case 'text':
    			case 'email':
    			case 'hidden':
    			case 'password':
    			case 'button':
    			case 'reset':
    			case 'submit':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'checkbox':
    			case 'radio':
            if (form.elements[i].checked) {
              obj[form.elements[i].name] = form.elements[i].value;
            } else if (!obj[form.elements[i].name]) {
              obj[form.elements[i].name] = false;
            }
    				break;
    			case 'file':
    				break;
    			}
    			break;
    		case 'TEXTAREA':
    			obj[form.elements[i].name] = form.elements[i].value;
    			break;
    		case 'SELECT':
    			switch (form.elements[i].type) {
    			case 'select-one':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'select-multiple':
    				for (let j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
    					if (form.elements[i].options[j].selected) {
    						obj[form.elements[i].name] = form.elements[i].options[j].value;
    					}
    				}
    				break;
    			}
    			break;
    		case 'BUTTON':
    			switch (form.elements[i].type) {
    			case 'reset':
    			case 'submit':
    			case 'button':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			}
    			break;
    		}
    	}
    	return obj;
    },

    validate(e) {
      e && e.preventDefault();
      let attributes = this.serialize(this.$form[0]);

      // Validate form, if is valid the response will be undefined
      this.errors = validate(attributes, constraints);
      return ! !!this.errors;
    },

    validateInput(name, value) {
      let errors = validate.single(value, constraints[name]);
      if (!!errors && this.errors) {
        this.errors[name] = errors[0];
      } else {
        this.errors && this.errors[name] && delete this.errors[name];
      }
    },

    changeInput(e) {
      e && e.preventDefault();
      this.validateInput(e.currentTarget.name, e.currentTarget.value);
      this.updateForm();
    },

    changeStep(step) {
      this.$step.removeClass('-active');
      this.$stepBtn.removeClass('-active');

      // Set actives
      this.$el.find('.step[data-step="'+step+'"]').addClass('-active');
      this.$el.find('.step-btn[data-step="'+step+'"]').addClass('-active');
    },

    changeTopic(e) {
      var topic = e.currentTarget.value;
      if (!!topic) {
        var placeholder = topics[topic]['placeholder'];
        this.$contactMessage.attr('placeholder', placeholder);
      }
    }

  });

  return ContacUsView;
});
<commit_msg>Feat: Contact us - Scroll to top after the form is sent<commit_after>define([
  'jquery',
  'backbone'
], function($, Backbone) {

  'use strict';

  const topics = {
    'report-a-bug-or-error-on-gfw': {
      name: 'Report a bug or error on GFW',
      placeholder: 'Explain the bug or error and tell us where on the website you encountered it. What browser (e.g., Chrome version 50.0.2661.94 m) and operating system (e.g., Windows 8.1) do you use?',
    },
    'provide-feedback': {
      name: 'Provide feedback',
      placeholder: 'Tell us about your experience with GFW! Examples: How can we improve GFW? Why did you visit GFW? How do you use GFW? If and how is the information provided by GFW useful for your work? Are there any additional features and/or data that would be useful?  Was anything confusing or difficult to use?  Etc...',
    },
    'media-request': {
      name: 'Media request',
      placeholder: 'How can we help you?',
    },
    'data-related-inquiry': {
      name: 'Data-related inquiry or suggestion',
      placeholder: 'How can we help you?',
    },
    'gfw-commodities-inquiry': {
      name: 'GFW Commodities inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-fires-inquiry': {
      name: 'GFW Fires inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-climate-inquiry': {
      name: 'GFW Climate inquiry',
      placeholder: 'How can we help you?',
    },
    'gfw-water-inquiry': {
      name: 'GFW Water inquiry',
      placeholder: 'How can we help you?',
    },
    'general-inquiry': {
      name: 'General inquiry',
      placeholder: 'How can we help you?',
    },
  }

  const constraints = {
    'contact-email': {
      presence: true,
      email: true
    },
    'contact-topic': {
      presence: true
    },
    'contact-message': {
      presence: true
    }
  };

  var ContacUsView = Backbone.View.extend({

    el: '#contact_us',

    events: {
      'click .js-btn-submit': 'actionSubmit',
      'change input, textarea, select': 'changeInput',
      'change #contact-topic': 'changeTopic'
    },

    initialize: function() {
      this.$spinner = this.$el.find('.m-spinner');
      this.$form = this.$el.find('#contact-form');
      this.$step = this.$el.find('.step');
      this.$stepBtn = this.$el.find('.step-btn');
      this.$contactMessage = this.$el.find('#contact-message');
      this.$body = $('html, body');
      this.$container = $('.content-static');
    },

    actionSubmit(e) {
      e && e.preventDefault();
      (this.validate(e)) ? this.sendForm() : this.updateForm();
    },

    // Send the data to the API
    sendForm() {
      // Production send request
      // Send request
      this.$spinner.addClass('-start');
      var xhr = new XMLHttpRequest();

      xhr.open('POST', window.gfw.config.GFW_API_HOST + '/emails');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');

      xhr.onload = function() {
        if (xhr.status === 200 || xhr.status === 201) {
          this.$body.animate({
            scrollTop: this.$container.offset().top
          }, 'slow');
          this.changeStep('success');
          this.resetForm();
          this.$spinner.removeClass('-start');
        } else {
          this.changeStep('error');
          this.$spinner.removeClass('-start');
        }
      }.bind(this);

      xhr.onerror = () => {
        this.changeStep('error');
        this.$spinner.removeClass('-start');
      }

      xhr.send(JSON.stringify(this.serialize(this.$form[0])));

      // // Develop Send request
      // // Comment this code if this is going to pro
      // if (true) {
      //   this.changeStep('success');
      //   this.$spinner.removeClass('-start');
      // } else {
      //   this.changeStep('error');
      //   this.$spinner.removeClass('-start');
      // }
    },

    updateForm() {
      this.$form.find('input, textarea, select').removeClass('-error');
      this.$form.find('label').removeClass('-error');
      for (var key in this.errors) {
        var $input = this.$form.find('#'+key);
        var $label = this.$form.find('label[for='+key+']');
        $input.addClass('-error');
        $label.addClass('-error');
      }
    },

    resetForm() {
      this.$form.find('input, textarea, select').val(null);
    },

    serialize(form) {
    	if (!form || form.nodeName !== "FORM") {
    		return;
    	}
    	let obj = {};
    	for (let i = form.elements.length - 1; i >= 0; i = i - 1) {
    		if (form.elements[i].name === "") {
    			continue;
    		}
    		switch (form.elements[i].nodeName) {
    		case 'INPUT':
    			switch (form.elements[i].type) {
    			case 'text':
    			case 'email':
    			case 'hidden':
    			case 'password':
    			case 'button':
    			case 'reset':
    			case 'submit':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'checkbox':
    			case 'radio':
            if (form.elements[i].checked) {
              obj[form.elements[i].name] = form.elements[i].value;
            } else if (!obj[form.elements[i].name]) {
              obj[form.elements[i].name] = false;
            }
    				break;
    			case 'file':
    				break;
    			}
    			break;
    		case 'TEXTAREA':
    			obj[form.elements[i].name] = form.elements[i].value;
    			break;
    		case 'SELECT':
    			switch (form.elements[i].type) {
    			case 'select-one':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			case 'select-multiple':
    				for (let j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
    					if (form.elements[i].options[j].selected) {
    						obj[form.elements[i].name] = form.elements[i].options[j].value;
    					}
    				}
    				break;
    			}
    			break;
    		case 'BUTTON':
    			switch (form.elements[i].type) {
    			case 'reset':
    			case 'submit':
    			case 'button':
    				obj[form.elements[i].name] = form.elements[i].value;
    				break;
    			}
    			break;
    		}
    	}
    	return obj;
    },

    validate(e) {
      e && e.preventDefault();
      let attributes = this.serialize(this.$form[0]);

      // Validate form, if is valid the response will be undefined
      this.errors = validate(attributes, constraints);
      return ! !!this.errors;
    },

    validateInput(name, value) {
      let errors = validate.single(value, constraints[name]);
      if (!!errors && this.errors) {
        this.errors[name] = errors[0];
      } else {
        this.errors && this.errors[name] && delete this.errors[name];
      }
    },

    changeInput(e) {
      e && e.preventDefault();
      this.validateInput(e.currentTarget.name, e.currentTarget.value);
      this.updateForm();
    },

    changeStep(step) {
      this.$step.removeClass('-active');
      this.$stepBtn.removeClass('-active');

      // Set actives
      this.$el.find('.step[data-step="'+step+'"]').addClass('-active');
      this.$el.find('.step-btn[data-step="'+step+'"]').addClass('-active');
    },

    changeTopic(e) {
      var topic = e.currentTarget.value;
      if (!!topic) {
        var placeholder = topics[topic]['placeholder'];
        this.$contactMessage.attr('placeholder', placeholder);
      }
    }

  });

  return ContacUsView;
});
<|endoftext|>


<commit_before>/* @flow weak */
import CopyWebpackPlugin from 'copy-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import WebpackIsomorphicToolsPlugin from 'webpack-isomorphic-tools/plugin';
import autoprefixer from 'autoprefixer';
import config from '../src/server/config';
import constants from './constants';
import ip from 'ip';
import path from 'path';
import webpack from 'webpack';
import webpackIsomorphicAssets from './assets';

const webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(webpackIsomorphicAssets);

// cheap-module-eval-source-map, because we want the fastest original source.
// http://webpack.github.io/docs/configuration.html#devtool
const devtools = 'cheap-module-eval-source-map';

const loaders = {
  css: '',
  // Why not LESS or Stylus? The battle is over, let's focus on inline styles.
  scss: '!sass-loader',
  sass: '!sass-loader?indentedSyntax',
};

const serverIp = config.remoteHotReload
  ? ip.address() // Dynamic IP address enables hot reload on remote devices.
  : 'localhost';

const makeConfig = options => {
  const {
    isDevelopment,
  } = options;

  const stylesLoaders = Object.keys(loaders).map(ext => {
    const prefix = 'css-loader!postcss-loader';
    const extLoaders = prefix + loaders[ext];
    const loader = isDevelopment
      ? `style-loader!${extLoaders}`
      : ExtractTextPlugin.extract('style-loader', extLoaders);
    return {
      loader,
      test: new RegExp(`\\.(${ext})$`),
    };
  });

  const config = {
    hotPort: constants.HOT_RELOAD_PORT,
    cache: isDevelopment,
    debug: isDevelopment,
    devtool: isDevelopment ? devtools : '',
    entry: {
      app: isDevelopment ? [
        `webpack-hot-middleware/client?path=http://${serverIp}:${constants.HOT_RELOAD_PORT}/__webpack_hmr`,
        path.join(constants.SRC_DIR, 'browser/index.js'),
      ] : [
        path.join(constants.SRC_DIR, 'browser/index.js'),
      ],
    },
    module: {
      loaders: [
        {
          loader: 'url-loader?limit=10000',
          test: /\.(gif|jpg|png|svg)$/,
        }, {
          loader: 'url-loader?limit=1',
          test: /favicon\.ico$/,
        }, {
          loader: 'url-loader?limit=100000',
          test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
        }, {
          test: /\.js$/,
          exclude: constants.NODE_MODULES_DIR,
          loader: 'babel',
          query: {
            cacheDirectory: true,
            presets: ['es2015', 'react', 'stage-1'],
            plugins: [
              ['transform-runtime', {
                helpers: false,
                polyfill: false,
                regenerator: false,
              }],
              'add-module-exports',
            ],
            env: {
              production: {
                plugins: [
                  'transform-react-constant-elements',
                ],
              },
            },
          },
        },
        ...stylesLoaders,
      ],
    },
    output: isDevelopment ? {
      path: constants.BUILD_DIR,
      filename: '[name].js',
      chunkFilename: '[name]-[chunkhash].js',
      publicPath: `http://${serverIp}:${constants.HOT_RELOAD_PORT}/build/`,
    } : {
      path: constants.BUILD_DIR,
      filename: '[name]-[hash].js',
      chunkFilename: '[name]-[chunkhash].js',
      publicPath: '/assets/',
    },
    plugins: (() => {
      const plugins = [
        new webpack.DefinePlugin({
          'process.env': {
            IS_BROWSER: true, // Because webpack is used only for browser code.
            IS_SERVERLESS: JSON.stringify(process.env.IS_SERVERLESS || false),
            NODE_ENV: JSON.stringify(isDevelopment ? 'development' : 'production'),
            SERVER_URL: JSON.stringify(process.env.SERVER_URL || ''),
          },
        }),
      ];
      if (isDevelopment) {
        plugins.push(
          new webpack.optimize.OccurrenceOrderPlugin(),
          new webpack.HotModuleReplacementPlugin(),
          new webpack.NoErrorsPlugin(),
          webpackIsomorphicToolsPlugin.development()
        );
      } else {
        plugins.push(
          // Render styles into separate cacheable file to prevent FOUC and
          // optimize for critical rendering path.
          new ExtractTextPlugin('app-[hash].css', {
            allChunks: true,
          }),
          new webpack.optimize.DedupePlugin(),
          new webpack.optimize.OccurrenceOrderPlugin(),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              screw_ie8: true, // eslint-disable-line camelcase
              warnings: false, // Because uglify reports irrelevant warnings.
            },
          }),
          new webpack.SourceMapDevToolPlugin({
            filename: '[file].map',
          }),
          webpackIsomorphicToolsPlugin,
          new CopyWebpackPlugin([{
            from: './src/common/app/favicons/',
            to: 'favicons',
          }], {
            ignore: ['original/**'],
          })
        );
      }
      return plugins;
    })(),
    postcss: () => [autoprefixer({ browsers: 'last 2 version' })],
    resolve: {
      extensions: ['', '.js'], // .json is ommited to ignore ./firebase.json
      modulesDirectories: ['src', 'node_modules'],
      root: constants.ABSOLUTE_BASE,
      alias: {
        react$: require.resolve(path.join(constants.NODE_MODULES_DIR, 'react')),
      },
    },
  };

  return config;
};

export default makeConfig;
<commit_msg>webpack devtools = eval<commit_after>/* @flow weak */
import CopyWebpackPlugin from 'copy-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import WebpackIsomorphicToolsPlugin from 'webpack-isomorphic-tools/plugin';
import autoprefixer from 'autoprefixer';
import config from '../src/server/config';
import constants from './constants';
import ip from 'ip';
import path from 'path';
import webpack from 'webpack';
import webpackIsomorphicAssets from './assets';

const webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(webpackIsomorphicAssets);

// github.com/facebookincubator/create-react-app/issues/343#issuecomment-237241875
// You may want 'cheap-module-source-map' instead if you prefer source maps.
const devtools = 'eval';

const loaders = {
  css: '',
  // Why not LESS or Stylus? The battle is over, let's focus on inline styles.
  scss: '!sass-loader',
  sass: '!sass-loader?indentedSyntax',
};

const serverIp = config.remoteHotReload
  ? ip.address() // Dynamic IP address enables hot reload on remote devices.
  : 'localhost';

const makeConfig = options => {
  const {
    isDevelopment,
  } = options;

  const stylesLoaders = Object.keys(loaders).map(ext => {
    const prefix = 'css-loader!postcss-loader';
    const extLoaders = prefix + loaders[ext];
    const loader = isDevelopment
      ? `style-loader!${extLoaders}`
      : ExtractTextPlugin.extract('style-loader', extLoaders);
    return {
      loader,
      test: new RegExp(`\\.(${ext})$`),
    };
  });

  const config = {
    hotPort: constants.HOT_RELOAD_PORT,
    cache: isDevelopment,
    debug: isDevelopment,
    devtool: isDevelopment ? devtools : '',
    entry: {
      app: isDevelopment ? [
        `webpack-hot-middleware/client?path=http://${serverIp}:${constants.HOT_RELOAD_PORT}/__webpack_hmr`,
        path.join(constants.SRC_DIR, 'browser/index.js'),
      ] : [
        path.join(constants.SRC_DIR, 'browser/index.js'),
      ],
    },
    module: {
      loaders: [
        {
          loader: 'url-loader?limit=10000',
          test: /\.(gif|jpg|png|svg)$/,
        }, {
          loader: 'url-loader?limit=1',
          test: /favicon\.ico$/,
        }, {
          loader: 'url-loader?limit=100000',
          test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
        }, {
          test: /\.js$/,
          exclude: constants.NODE_MODULES_DIR,
          loader: 'babel',
          query: {
            cacheDirectory: true,
            presets: ['es2015', 'react', 'stage-1'],
            plugins: [
              ['transform-runtime', {
                helpers: false,
                polyfill: false,
                regenerator: false,
              }],
              'add-module-exports',
            ],
            env: {
              production: {
                plugins: [
                  'transform-react-constant-elements',
                ],
              },
            },
          },
        },
        ...stylesLoaders,
      ],
    },
    output: isDevelopment ? {
      path: constants.BUILD_DIR,
      filename: '[name].js',
      chunkFilename: '[name]-[chunkhash].js',
      publicPath: `http://${serverIp}:${constants.HOT_RELOAD_PORT}/build/`,
    } : {
      path: constants.BUILD_DIR,
      filename: '[name]-[hash].js',
      chunkFilename: '[name]-[chunkhash].js',
      publicPath: '/assets/',
    },
    plugins: (() => {
      const plugins = [
        new webpack.DefinePlugin({
          'process.env': {
            IS_BROWSER: true, // Because webpack is used only for browser code.
            IS_SERVERLESS: JSON.stringify(process.env.IS_SERVERLESS || false),
            NODE_ENV: JSON.stringify(isDevelopment ? 'development' : 'production'),
            SERVER_URL: JSON.stringify(process.env.SERVER_URL || ''),
          },
        }),
      ];
      if (isDevelopment) {
        plugins.push(
          new webpack.optimize.OccurrenceOrderPlugin(),
          new webpack.HotModuleReplacementPlugin(),
          new webpack.NoErrorsPlugin(),
          webpackIsomorphicToolsPlugin.development()
        );
      } else {
        plugins.push(
          // Render styles into separate cacheable file to prevent FOUC and
          // optimize for critical rendering path.
          new ExtractTextPlugin('app-[hash].css', {
            allChunks: true,
          }),
          new webpack.optimize.DedupePlugin(),
          new webpack.optimize.OccurrenceOrderPlugin(),
          new webpack.optimize.UglifyJsPlugin({
            compress: {
              screw_ie8: true, // eslint-disable-line camelcase
              warnings: false, // Because uglify reports irrelevant warnings.
            },
          }),
          new webpack.SourceMapDevToolPlugin({
            filename: '[file].map',
          }),
          webpackIsomorphicToolsPlugin,
          new CopyWebpackPlugin([{
            from: './src/common/app/favicons/',
            to: 'favicons',
          }], {
            ignore: ['original/**'],
          })
        );
      }
      return plugins;
    })(),
    postcss: () => [autoprefixer({ browsers: 'last 2 version' })],
    resolve: {
      extensions: ['', '.js'], // .json is ommited to ignore ./firebase.json
      modulesDirectories: ['src', 'node_modules'],
      root: constants.ABSOLUTE_BASE,
      alias: {
        react$: require.resolve(path.join(constants.NODE_MODULES_DIR, 'react')),
      },
    },
  };

  return config;
};

export default makeConfig;
<|endoftext|>


<commit_before>import { BrowserWindow, globalShortcut, app, screen, shell } from 'electron'
import debounce from 'lodash/debounce'
import EventEmitter from 'events'
import trackEvent from '../lib/trackEvent'

import {
  INPUT_HEIGHT,
  WINDOW_WIDTH
} from './constants/ui'

import buildMenu from './createWindow/buildMenu'
import toggleWindow from './createWindow/toggleWindow'
import handleUrl from './createWindow/handleUrl'
import config from '../lib/config'
import getWindowPosition from '../lib/getWindowPosition'

export default ({ src, isDev }) => {
  const [x, y] = getWindowPosition({})

  const mainWindow = new BrowserWindow({
    width: WINDOW_WIDTH,
    minWidth: WINDOW_WIDTH,
    height: INPUT_HEIGHT,
    x,
    y,
    frame: false,
    resizable: false,
    // Show main window on launch only when application started for the first time
    show: config.get('firstStart')
  })

  // Float main window above full-screen apps
  mainWindow.setAlwaysOnTop(true, 'modal-panel')

  mainWindow.loadURL(src)
  mainWindow.settingsChanges = new EventEmitter()

  // Get global shortcut from app settings
  let shortcut = config.get('hotkey')

  // Function to toggle main window
  const toggleMainWindow = () => toggleWindow(mainWindow)
  // Function to show main window
  const showMainWindow = () => {
    mainWindow.show()
    mainWindow.focus()
  }

  // Setup event listeners for main window
  globalShortcut.register(shortcut, toggleMainWindow)

  mainWindow.on('blur', () => {
    if (!isDev()) {
      // Hide window on blur in production
      // In development we usually use developer tools that can blur a window
      mainWindow.hide()
    }
  })

  // Save window position when it is being moved
  mainWindow.on('move', debounce(() => {
    if (!mainWindow.isVisible()) {
      return
    }
    const display = screen.getPrimaryDisplay()
    const positions = config.get('positions') || {}
    positions[display.id] = mainWindow.getPosition()
    config.set('positions', positions)
  }, 100))

  mainWindow.on('close', app.quit)

  mainWindow.webContents.on('new-window', (event, url) => {
    shell.openExternal(url)
    event.preventDefault()
  })

  mainWindow.webContents.on('will-navigate', (event, url) => {
    if (url !== mainWindow.webContents.getURL()) {
      shell.openExternal(url)
      event.preventDefault()
    }
  })

  // Change global hotkey if it is changed in app settings
  mainWindow.settingsChanges.on('hotkey', (value) => {
    globalShortcut.unregister(shortcut)
    shortcut = value
    globalShortcut.register(shortcut, toggleMainWindow)
  })

  // Change theme css file
  mainWindow.settingsChanges.on('theme', (value) => {
    mainWindow.webContents.send('message', {
      message: 'updateTheme',
      payload: value
    })
  })

  // Handle window.hide: if cleanOnHide value in preferences is true
  // we clear all results and show empty window every time
  const resetResults = () => {
    mainWindow.webContents.send('message', {
      message: 'showTerm',
      payload: ''
    })
  }

  // Handle change of cleanOnHide value in settins
  const handleCleanOnHideChange = (value) => {
    if (value) {
      mainWindow.on('hide', resetResults)
    } else {
      mainWindow.removeListener('hide', resetResults)
    }
  }

  // Set or remove handler when settings changed
  mainWindow.settingsChanges.on('cleanOnHide', handleCleanOnHideChange)

  // Set initial handler if it is needed
  handleCleanOnHideChange(config.get('cleanOnHide'))

  // Show main window when user opens application, but it is already opened
  app.on('open-file', (event, path) => handleUrl(mainWindow, path))
  app.on('open-url', (event, path) => handleUrl(mainWindow, path))
  app.on('activate', showMainWindow)

  // Track app start event
  trackEvent({
    category: 'App Start',
    event: config.get('firstStart') ? 'First' : 'Secondary'
  })

  // Save in config information, that application has been started
  config.set('firstStart', false)

  buildMenu(mainWindow)
  return mainWindow
}
<commit_msg>Single Instance Application<commit_after>import { BrowserWindow, globalShortcut, app, screen, shell } from 'electron'
import debounce from 'lodash/debounce'
import EventEmitter from 'events'
import trackEvent from '../lib/trackEvent'

import {
  INPUT_HEIGHT,
  WINDOW_WIDTH
} from './constants/ui'

import buildMenu from './createWindow/buildMenu'
import toggleWindow from './createWindow/toggleWindow'
import handleUrl from './createWindow/handleUrl'
import config from '../lib/config'
import getWindowPosition from '../lib/getWindowPosition'

export default ({ src, isDev }) => {
  const [x, y] = getWindowPosition({})

  const mainWindow = new BrowserWindow({
    width: WINDOW_WIDTH,
    minWidth: WINDOW_WIDTH,
    height: INPUT_HEIGHT,
    x,
    y,
    frame: false,
    resizable: false,
    // Show main window on launch only when application started for the first time
    show: config.get('firstStart')
  })

  // Float main window above full-screen apps
  mainWindow.setAlwaysOnTop(true, 'modal-panel')

  mainWindow.loadURL(src)
  mainWindow.settingsChanges = new EventEmitter()

  // Get global shortcut from app settings
  let shortcut = config.get('hotkey')

  // Function to toggle main window
  const toggleMainWindow = () => toggleWindow(mainWindow)
  // Function to show main window
  const showMainWindow = () => {
    mainWindow.show()
    mainWindow.focus()
  }

  // Setup event listeners for main window
  globalShortcut.register(shortcut, toggleMainWindow)

  mainWindow.on('blur', () => {
    if (!isDev()) {
      // Hide window on blur in production
      // In development we usually use developer tools that can blur a window
      mainWindow.hide()
    }
  })

  // Save window position when it is being moved
  mainWindow.on('move', debounce(() => {
    if (!mainWindow.isVisible()) {
      return
    }
    const display = screen.getPrimaryDisplay()
    const positions = config.get('positions') || {}
    positions[display.id] = mainWindow.getPosition()
    config.set('positions', positions)
  }, 100))

  mainWindow.on('close', app.quit)

  mainWindow.webContents.on('new-window', (event, url) => {
    shell.openExternal(url)
    event.preventDefault()
  })

  mainWindow.webContents.on('will-navigate', (event, url) => {
    if (url !== mainWindow.webContents.getURL()) {
      shell.openExternal(url)
      event.preventDefault()
    }
  })

  // Change global hotkey if it is changed in app settings
  mainWindow.settingsChanges.on('hotkey', (value) => {
    globalShortcut.unregister(shortcut)
    shortcut = value
    globalShortcut.register(shortcut, toggleMainWindow)
  })

  // Change theme css file
  mainWindow.settingsChanges.on('theme', (value) => {
    mainWindow.webContents.send('message', {
      message: 'updateTheme',
      payload: value
    })
  })

  // Handle window.hide: if cleanOnHide value in preferences is true
  // we clear all results and show empty window every time
  const resetResults = () => {
    mainWindow.webContents.send('message', {
      message: 'showTerm',
      payload: ''
    })
  }

  // Handle change of cleanOnHide value in settins
  const handleCleanOnHideChange = (value) => {
    if (value) {
      mainWindow.on('hide', resetResults)
    } else {
      mainWindow.removeListener('hide', resetResults)
    }
  }

  // Set or remove handler when settings changed
  mainWindow.settingsChanges.on('cleanOnHide', handleCleanOnHideChange)

  // Set initial handler if it is needed
  handleCleanOnHideChange(config.get('cleanOnHide'))

  // Show main window when user opens application, but it is already opened
  app.on('open-file', (event, path) => handleUrl(mainWindow, path))
  app.on('open-url', (event, path) => handleUrl(mainWindow, path))
  app.on('activate', showMainWindow)

  // Someone tried to run a second instance, we should focus our window.
  const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
    }
  })

  if (shouldQuit) {
    app.quit()
  }

  // Track app start event
  trackEvent({
    category: 'App Start',
    event: config.get('firstStart') ? 'First' : 'Secondary'
  })

  // Save in config information, that application has been started
  config.set('firstStart', false)

  buildMenu(mainWindow)
  return mainWindow
}
<|endoftext|>


<commit_before>const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');

const server = express();

const Bookmark = require('./models/bookmark');

server.use(bodyParser.json());

server.use('/', express.static(path.resolve(__dirname, 'public')));

server.get('/', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'index.html'));
});

const apiV1Route = express.Router();

apiV1Route.get('/bookmarks', async (req, res) => {
  const bookmarks = await Bookmark.findAll();
  res.json(bookmarks);
});

apiV1Route.post('/bookmarks', async (req, res) => {
  const { repo_id, full_name } = req.body;

  try {
    if (!repo_id || !full_name) {
      throw new Error('Missing parameters');
    }

    if (Math.round(Math.random())) {
      throw new Error('Something happended');
    }

    const bookmarks = await Bookmark.findOrCreate({ where: { repo_id, full_name } });

    res.json(bookmarks[0]);
  } catch (error) {
    res
      .status(400)
      .json({ message: error.message });
  };
});

apiV1Route.delete('/bookmarks/:repo_id', async (req, res) => {
  const { repo_id } = req.params;

  try {
    if (Math.round(Math.random())) {
      throw new Error('Something happended');
    }

    await Bookmark.destroy({ where: { repo_id } });

    res.sendStatus(204);
  } catch (error) {
    res
      .sendStatus(404);
  }
})

server.use('/api/v1', apiV1Route);

server.listen('3000', () => {
  console.log('> Server is ready on port 3000.')
});
<commit_msg>Listen port can be changed by giving specific port when starting the node server.<commit_after>const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');

const server = express();

const Bookmark = require('./models/bookmark');

const port = process.env.PORT || 3000;

server.use(bodyParser.json());

server.use('/', express.static(path.resolve(__dirname, 'public')));

server.get('/', (req, res) => {
  res.sendFile(path.resolve(__dirname, 'index.html'));
});

const apiV1Route = express.Router();

apiV1Route.get('/bookmarks', async (req, res) => {
  const bookmarks = await Bookmark.findAll();
  res.json(bookmarks);
});

apiV1Route.post('/bookmarks', async (req, res) => {
  const { repo_id, full_name } = req.body;

  try {
    if (!repo_id || !full_name) {
      throw new Error('Missing parameters');
    }

    if (Math.round(Math.random())) {
      throw new Error('Something happended');
    }

    const bookmarks = await Bookmark.findOrCreate({ where: { repo_id, full_name } });

    res.json(bookmarks[0]);
  } catch (error) {
    res
      .status(400)
      .json({ message: error.message });
  };
});

apiV1Route.delete('/bookmarks/:repo_id', async (req, res) => {
  const { repo_id } = req.params;

  try {
    if (Math.round(Math.random())) {
      throw new Error('Something happended');
    }

    await Bookmark.destroy({ where: { repo_id } });

    res.sendStatus(204);
  } catch (error) {
    res
      .sendStatus(404);
  }
})

server.use('/api/v1', apiV1Route);

server.listen(port, () => {
  console.log(`> Server is ready on port ${port}.`);
});
<|endoftext|>


<commit_before>'use strict';
require('babel-register');

const express = require('express');
const proxy = require('proxy-middleware');
const url = require('url');
const cookieParser = require('cookie-parser');
const compress = require('compression');
const auth = require('http-auth');
const path = require('path');
const compression = require('compression');
const config = require('./config/server_config.js');

//to throw uncaught exception error
process.on('uncaughtException',  (exception) => {
  console.log(JSON.stringify(exception));
  console.log(exception.stack);
});

const app = express();
app.use(cookieParser());

//gzip response
app.use(compress());
app.enable('trust proxy');

// app.use (function (req, res, next) {
//   if(req.headers["x-forwarded-proto"] === "https" || req.hostname === 'localhost'){
//     return next();
//   };
//   res.redirect('https://'+req.hostname+req.url);
// });

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(express.static(path.join('./')));

app.get('*', function(req, res) {
  res.sendFile(__dirname + '/index.html');
});

app.listen(config.PORT, () => {
  console.log('App running on' + config.PORT);
});
<commit_msg>heroku port added<commit_after>'use strict';
require('babel-register');

const express = require('express');
const proxy = require('proxy-middleware');
const url = require('url');
const cookieParser = require('cookie-parser');
const compress = require('compression');
const auth = require('http-auth');
const path = require('path');
const compression = require('compression');
const config = require('./config/server_config.js');
const port = process.env.PORT || 8080;

//to throw uncaught exception error
process.on('uncaughtException',  (exception) => {
  console.log(JSON.stringify(exception));
  console.log(exception.stack);
});

const app = express();
app.use(cookieParser());

//gzip response
app.use(compress());
app.enable('trust proxy');

// app.use (function (req, res, next) {
//   if(req.headers["x-forwarded-proto"] === "https" || req.hostname === 'localhost'){
//     return next();
//   };
//   res.redirect('https://'+req.hostname+req.url);
// });

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(express.static(path.join('./')));

app.get('*', function(req, res) {
  res.sendFile(__dirname + '/index.html');
});

app.listen(port, () => {
  console.log('App running on' + port);
});
<|endoftext|>


<commit_before>'use strict'
var vmCall = require('../vmCall')
var remixLib = require('remix-lib')
var traceHelper = remixLib.helpers.trace
var SolidityProxy = require('../../../src/solidity-decoder/solidityProxy')
var InternalCallTree = require('../../../src/solidity-decoder/internalCallTree')
var EventManager = remixLib.EventManager
var helper = require('./helper')

var TraceManager = remixLib.trace.TraceManager
var CodeManager = remixLib.code.CodeManager

module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) {
  vmCall.sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, contractBytecode, function (error, txHash) {
    if (error) {
      st.fail(error)
    } else {
      vm.web3.eth.getTransaction(txHash, function (error, tx) {
        if (error) {
          st.fail(error)
        } else {
          tx.to = traceHelper.contractCreationToken('0')
          var traceManager = new TraceManager({web3: vm.web3})
          var codeManager = new CodeManager(traceManager)
          codeManager.clear()
          var solidityProxy = new SolidityProxy(traceManager, codeManager)
          solidityProxy.reset(compilationResult)
          var debuggerEvent = new EventManager()
          var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true })
          callTree.event.register('callTreeBuildFailed', (error) => {
            st.fail(error)
          })
          callTree.event.register('callTreeReady', (scopes, scopeStarts) => {
            helper.decodeLocals(st, 1587, traceManager, callTree, function (locals) {
              try {
                st.equals(locals['bytesSimple'].length, '0x14')
                st.equals(locals['bytesSimple'].value, '0x746573745f7375706572')
                st.equals(locals['e'].value['a'].value, 'test')
                st.equals(locals['e'].value['a'].length, '0x8')
                st.equals(locals['e'].value['a'].raw, '0x74657374')
                st.equals(locals['e'].value['b'].value, '5')
                st.equals(locals['e'].value['c'].length, '0x220')
                st.equals(locals['e'].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374')
                st.equals(locals['e'].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test')
                st.equals(locals['e'].value['d'].value, '3')
                st.equals(locals['f'].length, '0x1b8')
                st.equals(locals['f'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f')
                st.equals(locals['f'].value, 'test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_')
                st.equals(locals['e'].value['e'].value, true)

                st.equals(locals['simpleArray'].value[0].value, '45')
                st.equals(locals['simpleArray'].value[1].value, '324324')
                st.equals(locals['simpleArray'].value[2].value, '-333')
                st.equals(locals['simpleArray'].value[3].value, '5656')
                st.equals(locals['simpleArray'].value[4].value, '-1111')

                st.equals(locals['stringArray'].value[0].value, 'long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_')
                st.equals(locals['stringArray'].value[1].value, 'two')
                st.equals(locals['stringArray'].value[2].value, 'three')

                st.equals(locals['dynArray'].value[0].value[0].value, '3423423532')
                st.equals(locals['dynArray'].value[1].value[0].value, '-342343323532')
                st.equals(locals['dynArray'].value[1].value[1].value, '23432')
                st.equals(locals['dynArray'].value[2].value[0].value, '-432432')
                st.equals(locals['dynArray'].value[2].value[1].value, '3423423532')
                st.equals(locals['dynArray'].value[2].value[2].value, '-432432')

                st.equals(locals['structArray'].value[0].value['a'].value, 'test')
                st.equals(locals['structArray'].value[0].value['a'].length, '0x8')
                st.equals(locals['structArray'].value[0].value['a'].raw, '0x74657374')
                st.equals(locals['structArray'].value[0].value['b'].value, '5')
                st.equals(locals['structArray'].value[0].value['c'].length, '0x220')
                st.equals(locals['structArray'].value[0].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374')
                st.equals(locals['structArray'].value[0].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test')
                st.equals(locals['structArray'].value[0].value['d'].value, '3')
                st.equals(locals['structArray'].value[0].value['e'].value, true)

                st.equals(locals['structArray'].value[1].value['a'].value, 'item1 a')
                st.equals(locals['structArray'].value[1].value['b'].value, '20')
                st.equals(locals['structArray'].value[1].value['c'].value, 'item1 c')
                st.equals(locals['structArray'].value[1].value['d'].value, '-45')
                st.equals(locals['structArray'].value[1].value['e'].value, false)

                st.equals(locals['structArray'].value[2].value['a'].value, 'item2 a')
                st.equals(locals['structArray'].value[2].value['b'].value, '200')
                st.equals(locals['structArray'].value[2].value['c'].value, 'item2 c')
                st.equals(locals['structArray'].value[2].value['d'].value, '-450')
                st.equals(locals['structArray'].value[2].value['e'].value, true)

                st.equals(locals['arrayStruct'].value.a.value[0].value, 'string')
                st.equals(locals['arrayStruct'].value.b.value[0].value, '34')
                st.equals(locals['arrayStruct'].value.b.value[1].value, '-23')
                st.equals(locals['arrayStruct'].value.b.value[2].value, '-3')
                st.equals(locals['arrayStruct'].value.c.value, 'three')

                st.equals(Object.keys(locals).length, 8)
              } catch (e) {
                st.fail(e.message)
              }
            })

            helper.decodeLocals(st, 7, traceManager, callTree, function (locals) {
              try {
                st.equals(0, 0)
                // st.equals(Object.keys(locals).length, 0)
              } catch (e) {
                st.fail(e.message)
              }
              cb()
            })
          })
          traceManager.resolveTrace(tx, (error, result) => {
            if (error) {
              st.fail(error)
            } else {
              debuggerEvent.trigger('newTraceLoaded', [traceManager.trace])
            }
          })
        }
      })
    }
  })
}
<commit_msg>fix_e2e_tests<commit_after>'use strict'
var vmCall = require('../vmCall')
var remixLib = require('remix-lib')
var traceHelper = remixLib.helpers.trace
var SolidityProxy = require('../../../src/solidity-decoder/solidityProxy')
var InternalCallTree = require('../../../src/solidity-decoder/internalCallTree')
var EventManager = remixLib.EventManager
var helper = require('./helper')

var TraceManager = remixLib.trace.TraceManager
var CodeManager = remixLib.code.CodeManager

module.exports = function (st, vm, privateKey, contractBytecode, compilationResult, cb) {
  vmCall.sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, contractBytecode, function (error, txHash) {
    if (error) {
      st.fail(error)
    } else {
      vm.web3.eth.getTransaction(txHash, function (error, tx) {
        if (error) {
          st.fail(error)
        } else {
          tx.to = traceHelper.contractCreationToken('0')
          var traceManager = new TraceManager({web3: vm.web3})
          var codeManager = new CodeManager(traceManager)
          codeManager.clear()
          var solidityProxy = new SolidityProxy(traceManager, codeManager)
          solidityProxy.reset(compilationResult)
          var debuggerEvent = new EventManager()
          var callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true })
          callTree.event.register('callTreeBuildFailed', (error) => {
            st.fail(error)
          })
          callTree.event.register('callTreeReady', (scopes, scopeStarts) => {
            helper.decodeLocals(st, 1622, traceManager, callTree, function (locals) {
              try {
                st.equals(locals['bytesSimple'].length, '0x14')
                st.equals(locals['bytesSimple'].value, '0x746573745f7375706572')
                st.equals(locals['e'].value['a'].value, 'test')
                st.equals(locals['e'].value['a'].length, '0x8')
                st.equals(locals['e'].value['a'].raw, '0x74657374')
                st.equals(locals['e'].value['b'].value, '5')
                st.equals(locals['e'].value['c'].length, '0x220')
                st.equals(locals['e'].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374')
                st.equals(locals['e'].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test')
                st.equals(locals['e'].value['d'].value, '3')
                st.equals(locals['f'].length, '0x1b8')
                st.equals(locals['f'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f')
                st.equals(locals['f'].value, 'test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_test_long_')
                st.equals(locals['e'].value['e'].value, true)

                st.equals(locals['simpleArray'].value[0].value, '45')
                st.equals(locals['simpleArray'].value[1].value, '324324')
                st.equals(locals['simpleArray'].value[2].value, '-333')
                st.equals(locals['simpleArray'].value[3].value, '5656')
                st.equals(locals['simpleArray'].value[4].value, '-1111')

                st.equals(locals['stringArray'].value[0].value, 'long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_long_one_')
                st.equals(locals['stringArray'].value[1].value, 'two')
                st.equals(locals['stringArray'].value[2].value, 'three')

                st.equals(locals['dynArray'].value[0].value[0].value, '3423423532')
                st.equals(locals['dynArray'].value[1].value[0].value, '-342343323532')
                st.equals(locals['dynArray'].value[1].value[1].value, '23432')
                st.equals(locals['dynArray'].value[2].value[0].value, '-432432')
                st.equals(locals['dynArray'].value[2].value[1].value, '3423423532')
                st.equals(locals['dynArray'].value[2].value[2].value, '-432432')

                st.equals(locals['structArray'].value[0].value['a'].value, 'test')
                st.equals(locals['structArray'].value[0].value['a'].length, '0x8')
                st.equals(locals['structArray'].value[0].value['a'].raw, '0x74657374')
                st.equals(locals['structArray'].value[0].value['b'].value, '5')
                st.equals(locals['structArray'].value[0].value['c'].length, '0x220')
                st.equals(locals['structArray'].value[0].value['c'].raw, '0x746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374746573745f6c6f6e675f746573745f6c6f6e675f746573745f6c6f6e675f74657374')
                st.equals(locals['structArray'].value[0].value['c'].value, 'test_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_testtest_long_test_long_test_long_test')
                st.equals(locals['structArray'].value[0].value['d'].value, '3')
                st.equals(locals['structArray'].value[0].value['e'].value, true)

                st.equals(locals['structArray'].value[1].value['a'].value, 'item1 a')
                st.equals(locals['structArray'].value[1].value['b'].value, '20')
                st.equals(locals['structArray'].value[1].value['c'].value, 'item1 c')
                st.equals(locals['structArray'].value[1].value['d'].value, '-45')
                st.equals(locals['structArray'].value[1].value['e'].value, false)

                st.equals(locals['structArray'].value[2].value['a'].value, 'item2 a')
                st.equals(locals['structArray'].value[2].value['b'].value, '200')
                st.equals(locals['structArray'].value[2].value['c'].value, 'item2 c')
                st.equals(locals['structArray'].value[2].value['d'].value, '-450')
                st.equals(locals['structArray'].value[2].value['e'].value, true)

                st.equals(locals['arrayStruct'].value.a.value[0].value, 'string')
                st.equals(locals['arrayStruct'].value.b.value[0].value, '34')
                st.equals(locals['arrayStruct'].value.b.value[1].value, '-23')
                st.equals(locals['arrayStruct'].value.b.value[2].value, '-3')
                st.equals(locals['arrayStruct'].value.c.value, 'three')

                st.equals(Object.keys(locals).length, 8)
              } catch (e) {
                st.fail(e.message)
              }
            })

            helper.decodeLocals(st, 7, traceManager, callTree, function (locals) {
              try {
                st.equals(0, 0)
                // st.equals(Object.keys(locals).length, 0)
              } catch (e) {
                st.fail(e.message)
              }
              cb()
            })
          })
          traceManager.resolveTrace(tx, (error, result) => {
            if (error) {
              st.fail(error)
            } else {
              debuggerEvent.trigger('newTraceLoaded', [traceManager.trace])
            }
          })
        }
      })
    }
  })
}
<|endoftext|>