<commit_before>// Don't use ES6 here to stay compatible with ESLint plugins

const webpack = require('webpack');
const ManifestPlugin = require('webpack-manifest-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const pkg = require('../package.json');
const _ = require('lodash');

global.__DEV__ = process.argv.length >= 3 && (process.argv[2].indexOf('watch') >= 0 || process.argv[1].indexOf('mocha-webpack') >= 0);
const buildNodeEnv = __DEV__ ? 'development' : 'production';

let basePlugins = [];

if (__DEV__) {
  basePlugins.push(new webpack.NamedModulesPlugin());
} else {
  basePlugins.push(new webpack.optimize.UglifyJsPlugin({ minimize: true }));
  basePlugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));
}

const baseConfig = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            "presets": ["react", ["es2015", { "modules": false }], "stage-2"],
            "plugins": [
              "transform-runtime",
              "transform-decorators-legacy",
              "transform-class-properties"
            ].concat(pkg.app.reactHotLoader ? ['react-hot-loader/babel'] : []),
            "only": ["*.js", "*.jsx"],
          }
        }
      },
      {
        test: /\.graphqls/,
        use: 'raw-loader'
      },
      {
        test: /\.(graphql|gql)$/,
        exclude: /node_modules/,
        use: [{
          loader: 'graphql-tag/loader',
        }]
      },
      {
        test: /\.(png|ico|jpg|xml)$/,
        use: 'url-loader?name=[hash].[ext]&limit=10000'
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'url-loader?name=./assets/[hash].[ext]&limit=10000'
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'file-loader?name=./assets/[hash].[ext]'
      },
    ]
  },
  resolve: {
    modules: [path.join(__dirname, '../src'), 'node_modules'],
    extensions: ['.js', '.jsx']
  },
  plugins: basePlugins,
  watchOptions: {
    ignored: /build/
  },
  bail: !__DEV__
};

let serverPlugins = [
  new webpack.BannerPlugin({ banner: 'require("source-map-support").install();',
      raw: true, entryOnly: false }),
  new webpack.DefinePlugin(Object.assign({__CLIENT__: false, __SERVER__: true, __SSR__: pkg.app.ssr,
    __DEV__: __DEV__, 'process.env.NODE_ENV': `"${buildNodeEnv}"`}))
];

const serverConfig = merge.smart(_.cloneDeep(baseConfig), {
  devtool: __DEV__ ? '#cheap-module-source-map' : '#source-map',
  target: 'node',
  entry: {
    index: ['babel-polyfill', './src/server/index.js']
  },
  node: {
    __dirname: true,
    __filename: true
  },
  externals: nodeExternals({
    whitelist: [/^webpack/]
  }),
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: __DEV__ ? [
          { loader: 'isomorphic-style-loader' },
          { loader: 'css-loader', options: { sourceMap: true } },
          { loader: 'postcss-loader' },
          { loader: 'sass-loader', options: { sourceMap: true } }] :
          [{ loader: 'ignore-loader' }]
      }
    ]
  },
  output: {
    devtoolModuleFilenameTemplate: __DEV__ ? '../../[resource-path]' : undefined,
    devtoolFallbackModuleFilenameTemplate: __DEV__ ? '../../[resource-path];[hash]' : undefined,
    filename: '[name].js',
    sourceMapFilename: '[name].[chunkhash].js.map',
    path: pkg.app.backendBuildDir,
    publicPath: '/'
  },
  plugins: serverPlugins
});

let clientPlugins = [
  new ManifestPlugin({
    fileName: 'assets.json'
  }),
  new webpack.DefinePlugin(Object.assign({__CLIENT__: true, __SERVER__: false, __SSR__: pkg.app.ssr,
    __DEV__: __DEV__, 'process.env.NODE_ENV': `"${buildNodeEnv}"`})),
];

if (!__DEV__) {
  clientPlugins.push(new ExtractTextPlugin({ filename: '[name].[contenthash].css', allChunks: true }));
  clientPlugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: "vendor",
    filename: "[name].[hash].js",
    minChunks: function (module) {
      return module.resource && module.resource.indexOf(path.resolve('./node_modules')) === 0;
    }
  }));
}

const clientConfig = merge.smart(_.cloneDeep(baseConfig), {
  devtool: __DEV__ ? '#eval' : '#source-map',
  entry: {
    bundle: ['babel-polyfill', './src/client/index.jsx']
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: __DEV__ ? [
          { loader: 'style-loader' },
          { loader: 'css-loader', options: { sourceMap: true, importLoaders: 1 } },
          { loader: 'postcss-loader', options: { sourceMap: true } },
          { loader: 'sass-loader', options: { sourceMap: true } },
        ] : ExtractTextPlugin.extract({ fallback: "style-loader",
          use: ['css-loader', 'postcss-loader', 'sass-loader']})
      }
    ]
  },
  output: {
    filename: '[name].[hash].js',
    path: pkg.app.frontendBuildDir,
    publicPath: '/'
  },
  plugins: clientPlugins
});

const dllConfig = merge.smart(_.cloneDeep(baseConfig), {
  entry: {
    vendor: _.keys(pkg.dependencies),
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]',
      path: path.join(pkg.app.frontendBuildDir, '[name]_dll.json'),
    }),
  ],
  output: {
    filename: '[name].[hash]_dll.js',
    path: pkg.app.frontendBuildDir,
    library: '[name]',
  },
});

module.exports =
  process.argv.length >= 2 && process.argv[1].indexOf('mocha-webpack') >= 0 ?
    serverConfig :
    [ serverConfig, clientConfig, dllConfig ];
<commit_msg>Turn on React Hot Loader only in dev mode<commit_after>// Don't use ES6 here to stay compatible with ESLint plugins

const webpack = require('webpack');
const ManifestPlugin = require('webpack-manifest-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const pkg = require('../package.json');
const _ = require('lodash');

global.__DEV__ = process.argv.length >= 3 && (process.argv[2].indexOf('watch') >= 0 || process.argv[1].indexOf('mocha-webpack') >= 0);
const buildNodeEnv = __DEV__ ? 'development' : 'production';

let basePlugins = [];

if (__DEV__) {
  basePlugins.push(new webpack.NamedModulesPlugin());
} else {
  basePlugins.push(new webpack.optimize.UglifyJsPlugin({ minimize: true }));
  basePlugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));
}

const baseConfig = {
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            "presets": ["react", ["es2015", { "modules": false }], "stage-2"],
            "plugins": [
              "transform-runtime",
              "transform-decorators-legacy",
              "transform-class-properties"
            ].concat(__DEV__ && pkg.app.reactHotLoader ? ['react-hot-loader/babel'] : []),
            "only": ["*.js", "*.jsx"],
          }
        }
      },
      {
        test: /\.graphqls/,
        use: 'raw-loader'
      },
      {
        test: /\.(graphql|gql)$/,
        exclude: /node_modules/,
        use: [{
          loader: 'graphql-tag/loader',
        }]
      },
      {
        test: /\.(png|ico|jpg|xml)$/,
        use: 'url-loader?name=[hash].[ext]&limit=10000'
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'url-loader?name=./assets/[hash].[ext]&limit=10000'
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        use: 'file-loader?name=./assets/[hash].[ext]'
      },
    ]
  },
  resolve: {
    modules: [path.join(__dirname, '../src'), 'node_modules'],
    extensions: ['.js', '.jsx']
  },
  plugins: basePlugins,
  watchOptions: {
    ignored: /build/
  },
  bail: !__DEV__
};

let serverPlugins = [
  new webpack.BannerPlugin({ banner: 'require("source-map-support").install();',
      raw: true, entryOnly: false }),
  new webpack.DefinePlugin(Object.assign({__CLIENT__: false, __SERVER__: true, __SSR__: pkg.app.ssr,
    __DEV__: __DEV__, 'process.env.NODE_ENV': `"${buildNodeEnv}"`}))
];

const serverConfig = merge.smart(_.cloneDeep(baseConfig), {
  devtool: __DEV__ ? '#cheap-module-source-map' : '#source-map',
  target: 'node',
  entry: {
    index: ['babel-polyfill', './src/server/index.js']
  },
  node: {
    __dirname: true,
    __filename: true
  },
  externals: nodeExternals({
    whitelist: [/^webpack/]
  }),
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: __DEV__ ? [
          { loader: 'isomorphic-style-loader' },
          { loader: 'css-loader', options: { sourceMap: true } },
          { loader: 'postcss-loader' },
          { loader: 'sass-loader', options: { sourceMap: true } }] :
          [{ loader: 'ignore-loader' }]
      }
    ]
  },
  output: {
    devtoolModuleFilenameTemplate: __DEV__ ? '../../[resource-path]' : undefined,
    devtoolFallbackModuleFilenameTemplate: __DEV__ ? '../../[resource-path];[hash]' : undefined,
    filename: '[name].js',
    sourceMapFilename: '[name].[chunkhash].js.map',
    path: pkg.app.backendBuildDir,
    publicPath: '/'
  },
  plugins: serverPlugins
});

let clientPlugins = [
  new ManifestPlugin({
    fileName: 'assets.json'
  }),
  new webpack.DefinePlugin(Object.assign({__CLIENT__: true, __SERVER__: false, __SSR__: pkg.app.ssr,
    __DEV__: __DEV__, 'process.env.NODE_ENV': `"${buildNodeEnv}"`})),
];

if (!__DEV__) {
  clientPlugins.push(new ExtractTextPlugin({ filename: '[name].[contenthash].css', allChunks: true }));
  clientPlugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: "vendor",
    filename: "[name].[hash].js",
    minChunks: function (module) {
      return module.resource && module.resource.indexOf(path.resolve('./node_modules')) === 0;
    }
  }));
}

const clientConfig = merge.smart(_.cloneDeep(baseConfig), {
  devtool: __DEV__ ? '#eval' : '#source-map',
  entry: {
    bundle: ['babel-polyfill', './src/client/index.jsx']
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: __DEV__ ? [
          { loader: 'style-loader' },
          { loader: 'css-loader', options: { sourceMap: true, importLoaders: 1 } },
          { loader: 'postcss-loader', options: { sourceMap: true } },
          { loader: 'sass-loader', options: { sourceMap: true } },
        ] : ExtractTextPlugin.extract({ fallback: "style-loader",
          use: ['css-loader', 'postcss-loader', 'sass-loader']})
      }
    ]
  },
  output: {
    filename: '[name].[hash].js',
    path: pkg.app.frontendBuildDir,
    publicPath: '/'
  },
  plugins: clientPlugins
});

const dllConfig = merge.smart(_.cloneDeep(baseConfig), {
  entry: {
    vendor: _.keys(pkg.dependencies),
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]',
      path: path.join(pkg.app.frontendBuildDir, '[name]_dll.json'),
    }),
  ],
  output: {
    filename: '[name].[hash]_dll.js',
    path: pkg.app.frontendBuildDir,
    library: '[name]',
  },
});

module.exports =
  process.argv.length >= 2 && process.argv[1].indexOf('mocha-webpack') >= 0 ?
    serverConfig :
    [ serverConfig, clientConfig, dllConfig ];
<|endoftext|>


<commit_before>import Orbit from 'orbit/main';
import Transformable from 'orbit/transformable';
import TransformConnector from 'orbit/transform-connector';
import { Promise } from 'rsvp';

var primarySource,
    secondarySource,
    transformConnector;

var successfulOperation = function() {
  return new Promise(function(resolve, reject) {
    resolve(':)');
  });
};

var failedOperation = function() {
  return new Promise(function(resolve, reject) {
    reject(':(');
  });
};

///////////////////////////////////////////////////////////////////////////////

module("Orbit - TransformConnector", {
  setup: function() {
    Orbit.Promise = Promise;

    primarySource = {};
    Transformable.extend(primarySource);

    secondarySource = {};
    Transformable.extend(secondarySource);
  },

  teardown: function() {
    primarySource = null;
    secondarySource = null;
    transformConnector = null;

    Orbit.Promise = null;
  }
});

test("it exists", function() {
  transformConnector = new TransformConnector(primarySource, secondarySource);
  ok(transformConnector);
});

test("it is active by default exists", function() {
  transformConnector = new TransformConnector(primarySource, secondarySource);
  equal(transformConnector.isActive(), true);
});

test("it watches `didTransform` events on the source and applies them to the target", function() {
  expect(3);

  var order = 0;

  var op = {
    op: 'add',
    path: ['planet', '1', {id: 1, name: 'Earth'}]
  };

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return null;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation, op, 'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("it watches `didTransform` events on the source and applies them to the target", function() {
  expect(3);

  var order = 0;

  var op = {
    op: 'add',
    path: ['planet', '1'],
    value: {id: 1, name: 'Earth'}
  };

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return null;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation, op, 'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("for `add` operations, it applies a differential if the target path exists", function() {
  expect(3);

  var order = 0;

  var op = {
    op: 'add',
    path: ['planet', '1'],
    value: {id: 1, name: 'Earth', hasRings: false}
  };

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return {
      id: 1,
      name: 'Saturn',
      hasRings: true
    };
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation,
              [{op: 'replace', path: 'planet/1/name', value: 'Earth'},
               {op: 'replace', path: 'planet/1/hasRings', value: false}],
              'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("for `replace` operations, it applies a differential if the target path exists", function() {
  expect(3);

  var order = 0;

  var op = {
    op: 'replace',
    path: ['planet', '1', 'hasRings'],
    value: true
  };

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return false;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation,
              [{op: 'replace', path: 'planet/1/hasRings', value: true}],
              'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

/*
 TODO - tests needed

 - filterFunction
 - activate / deactivate
 - queueing
 - blocking vs. non-blocking
  */
<commit_msg>Use Operation instances to test TransformConnector.<commit_after>import Orbit from 'orbit/main';
import Operation from 'orbit/operation';
import Transformable from 'orbit/transformable';
import TransformConnector from 'orbit/transform-connector';
import { Promise } from 'rsvp';
import { equalOps } from 'tests/test-helper';

var primarySource,
    secondarySource,
    transformConnector;

var successfulOperation = function() {
  return new Promise(function(resolve, reject) {
    resolve(':)');
  });
};

var failedOperation = function() {
  return new Promise(function(resolve, reject) {
    reject(':(');
  });
};

///////////////////////////////////////////////////////////////////////////////

module("Orbit - TransformConnector", {
  setup: function() {
    Orbit.Promise = Promise;

    primarySource = {};
    Transformable.extend(primarySource);

    secondarySource = {};
    Transformable.extend(secondarySource);
  },

  teardown: function() {
    primarySource = null;
    secondarySource = null;
    transformConnector = null;

    Orbit.Promise = null;
  }
});

test("it exists", function() {
  transformConnector = new TransformConnector(primarySource, secondarySource);
  ok(transformConnector);
});

test("it is active by default exists", function() {
  transformConnector = new TransformConnector(primarySource, secondarySource);
  equal(transformConnector.isActive(), true);
});

test("it watches `didTransform` events on the source and applies them to the target", function() {
  expect(3);

  var order = 0;

  var op = new Operation({
    op: 'add',
    path: ['planet', '1', {id: 1, name: 'Earth'}]
  });

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return null;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation, op, 'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("it watches `didTransform` events on the source and applies them to the target", function() {
  expect(3);

  var order = 0;

  var op = new Operation({
    op: 'add',
    path: ['planet', '1'],
    value: {id: 1, name: 'Earth'}
  });

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return null;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    deepEqual(operation, op, 'target operation matches source operation');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("for `add` operations, it applies a differential if the target path exists", function() {
  expect(5);

  var order = 0;

  var op = new Operation({
    op: 'add',
    path: ['planet', '1'],
    value: {id: 1, name: 'Earth', hasRings: false}
  });

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return {
      id: 1,
      name: 'Saturn',
      hasRings: true
    };
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    equal(operation.length, 2, 'target operation count matches');
    equalOps(operation[0], {op: 'replace', path: 'planet/1/name', value: 'Earth'}, 'first target op matches');
    equalOps(operation[1], {op: 'replace', path: 'planet/1/hasRings', value: false}, 'second target op matches');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

test("for `replace` operations, it applies a differential if the target path exists", function() {
  expect(4);

  var order = 0;

  var op = new Operation({
    op: 'replace',
    path: ['planet', '1', 'hasRings'],
    value: true
  });

  secondarySource.retrieve = function() {
    equal(++order, 1, 'target.retrieve triggered');
    return false;
  };

  secondarySource.transform = function(operation) {
    start();
    equal(++order, 2, 'target.transform triggered');
    equal(operation.length, 1, 'target operation count matches');
    equalOps(operation[0], {op: 'replace', path: 'planet/1/hasRings', value: true}, 'first target op matches');
    return successfulOperation();
  };

  transformConnector = new TransformConnector(primarySource, secondarySource);

  stop();
  primarySource.emit('didTransform', op);
});

/*
 TODO - tests needed

 - filterFunction
 - activate / deactivate
 - queueing
 - blocking vs. non-blocking
*/
<|endoftext|>


<commit_before>const {resolve} = require('path');
const webpack =require('webpack');

module.exports = {
    entry: [
        './index.tsx'
    ],
    output:{
        filename: 'bundle.js',
        path: resolve(__dirname, 'static'),
        publicPath: ''
    },
    resolve:{
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
    },
    context: resolve(__dirname, 'src'),
    devtool: 'inline-source-map',
    devServer:{
        hot: true,
        contentBase: resolve(__dirname, 'static'),
        publicPath: ''
    },
    module: {
        rules:[{
                test: /\.(ts|tsx)$/,
                use: ['awesome-typescript-loader']
            },{
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: []
};
<commit_msg>changing JavaScript standard for webpackconfig.<commit_after>var {resolve} = require('path');
var webpack =require('webpack');

module.exports = {
    entry: [
        './index.tsx'
    ],
    output:{
        filename: 'bundle.js',
        path: resolve(__dirname, 'static'),
        publicPath: ''
    },
    resolve:{
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.css']
    },
    context: resolve(__dirname, 'src'),
    devtool: 'inline-source-map',
    devServer:{
        hot: true,
        contentBase: resolve(__dirname, 'static'),
        publicPath: ''
    },
    module: {
        rules:[{
                test: /\.(ts|tsx)$/,
                use: ['awesome-typescript-loader']
            },{
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: []
};
<|endoftext|>


<commit_before>/**
 * @file for config stuff that's used for webpack configuration, but isn't passed to webpack compiler
 */

import path from 'path'
import manifest from '../static/manifest'

let {
	BASE_API,
	NODE_ENV,
	SENTRY_DSN_PUBLIC,
	GA_ID,
	JWT_SECRET,
	ANALYZE_BUNDLE,
	SENTRY_DSN,
	HTTP_PORT,
	HTTPS_PORT
} = process.env

// Vars for both server and frontend
BASE_API = BASE_API || '/api/v1'
NODE_ENV = NODE_ENV || 'development'

// Paths
const rootPath = path.join(__dirname, '../') // = "/"
const distPath = path.join(rootPath, './dist') // = "/dist"
const srcPath = path.join(rootPath, './src') // = "/src"
const srcCommonPath = path.join(srcPath, './common') // = "/src/common"

// Vars for server only
const CLIENT_DIST_PATH = path.join(distPath, './client') // = "/dist/client"
JWT_SECRET = JWT_SECRET || 'secret'
HTTP_PORT = HTTP_PORT || 3000
HTTPS_PORT = HTTPS_PORT || 3030

// compute isProduction based on NODE_ENV
const isProduction = process.env.NODE_ENV === 'production'

export default {
	title: 'Suicrux',
	publicPath: '/',
	// i18n object
	isProduction,
	// Env vars
	BASE_API,
	NODE_ENV,
	SENTRY_DSN_PUBLIC,
	ANALYZE_BUNDLE,
	GA_ID,
	CLIENT_DIST_PATH,
	JWT_SECRET,
	SENTRY_DSN,
	HTTPS_PORT,
	HTTP_PORT,
	// It's better to define pathes in one file
	// and then use everywhere across app
	srcPath,
	srcCommonPath,
	distPath,
	rootPath,
	// text for WebpackBannerPlugin
	banner:
		'Apache 2 License. Copyright (c) 2017 Vladimir Metnew All Rights Reserved. Repo: https://github.com/Metnew/suicrux',
	// your manifest.json
	manifest,
	vendor: [
		'react',
		'react-dom',
		'redux',
		'history',
		'react-router',
		'react-router-dom',
		'react-router-redux',
		'semantic-ui-react',
		'redux-thunk',
		'react-helmet',
		'lodash',
		'normalizr',
		'js-cookie',
		'prop-types',
		'store2',
		'styled-components',
		'react-headroom'
	],
	polyfills: ['promise-polyfill', 'isomorphic-fetch']
}
<commit_msg>fix(webpack_config): es6ify code<commit_after>/**
 * @file for config stuff that's used for webpack configuration, but isn't passed to webpack compiler
 */

import path from 'path'
import manifest from '../static/manifest'

const {
	BASE_API = '/api/v1',
	NODE_ENV = 'development',
	SENTRY_DSN_PUBLIC,
	GA_ID,
	JWT_SECRET = 'secret',
	ANALYZE_BUNDLE,
	SENTRY_DSN,
	HTTP_PORT = 3000
} = process.env

// Paths
const rootPath = path.join(__dirname, '../') // = "/"
const distPath = path.join(rootPath, './dist') // = "/dist"
const srcPath = path.join(rootPath, './src') // = "/src"
const srcCommonPath = path.join(srcPath, './common') // = "/src/common"

// Vars for server only
const CLIENT_DIST_PATH = path.join(distPath, './client') // = "/dist/client"

// compute isProduction based on NODE_ENV
const isProduction = process.env.NODE_ENV === 'production'

export default {
	title: 'Suicrux',
	publicPath: '/',
	// i18n object
	isProduction,
	// Env vars
	BASE_API,
	NODE_ENV,
	SENTRY_DSN_PUBLIC,
	ANALYZE_BUNDLE,
	GA_ID,
	CLIENT_DIST_PATH,
	JWT_SECRET,
	SENTRY_DSN,
	HTTP_PORT,
	// It's better to define pathes in one file
	// and then use everywhere across app
	srcPath,
	srcCommonPath,
	distPath,
	rootPath,
	// text for WebpackBannerPlugin
	banner:
		'Apache 2 License. Copyright (c) 2017 Vladimir Metnew All Rights Reserved. Repo: https://github.com/Metnew/suicrux',
	// your manifest.json
	manifest,
	vendor: [
		'react',
		'react-dom',
		'redux',
		'history',
		'react-router',
		'react-router-dom',
		'react-router-redux',
		'semantic-ui-react',
		'redux-thunk',
		'react-helmet',
		'lodash',
		'normalizr',
		'js-cookie',
		'prop-types',
		'store2',
		'styled-components',
		'react-headroom'
	],
	polyfills: ['promise-polyfill', 'isomorphic-fetch']
}
<|endoftext|>


<commit_before>(function ( $ ) {
  var regexs = {
    en: "[A-Za-z]+",
    ko: "[ㄱ-ㅎ가-힣]+",
    jp: "[\u3040-\u309F\u30A0-\u30FF]+",
    cn: "[\u4E00-\u9FBF]+",
    num: "[0-9]+",
    punct: "[\(\).,（）。、·，;:」“”\"\'\-<>\&]+"
  }

  function MultiLingual(params){
    this.containers = params.containers;
    this.configuration = params.configuration;

    this.init();
  }

  MultiLingual.prototype = {
    init: function(){
      this.finalRegex = this.composeRegex();

      for (var i = 0, len = this.containers.length; i < len; i++){
        var container = this.containers[i];

        this.recursiveChange(this.containers[0], container);
      }
    },

    recursiveChange: function(parent, dom){
      // debugger;
      if (dom.childNodes.length > 0) {
        for (var i = dom.childNodes.length - 1; i >= 0; i--) {
          this.recursiveChange(dom, dom.childNodes[i]);
        }
      } else {
        if (dom.nodeType === 3) {
          var configuration = this.configuration;

          var domStr = dom.textContent.replace(this.finalRegex, function(){
            for (var i = 1; i < arguments.length; i++) {
              if (arguments[i] != undefined) {
                var config = configuration[i - 1];
                var className;

                if (typeof config == "string"){
                  className = "ml-" + config;
                } else {
                  className = config.className;
                }

                return "" + arguments[i] + "";
              }
            }
          });

          var newDom = $.parseHTML(domStr);
          for (var i = 0; i < newDom.length; i++) {
            parent.insertBefore(newDom[i], dom);
          }

          dom.remove();
        }
      }
    },

    unescapeRegexStr: function(input) {
      return input.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">")
    },

    escapeRegexStr: function(str) {
      return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    computeCustomRegex: function (charset) {
      charset = this.escapeRegexStr(charset);

      var finalStr = "([" + charset + "]+)";
      return finalStr;
    },

    composeRegex: function(){
      var finalRegexStr = "(\?![^<>&]*>)";

      for (var i = 0, len = this.configuration.length; i < len; i++){
        var config = this.configuration[i];

        if (typeof config == "string"){ // ml-en 등 미리 정해진 프리셋의 경우
          finalRegexStr += "(" + regexs[config] + ")";
        } else {
          finalRegexStr += this.computeCustomRegex(config.charset);
        }

        if (i < this.configuration.length - 1) {
          finalRegexStr += "|";
        }
      }

      return new RegExp(finalRegexStr, "gm");
    }
  }

  $.fn.multilingual = function(params) {
    var multilingual = new MultiLingual({
      containers: this,
      configuration: params
    });

    return multilingual;
  };

}( jQuery ));<commit_msg>알수는 없지만 온점-숫자 버그 해결<commit_after>(function ( $ ) {
  var regexs = {
    en: "[A-Za-z]+",
    ko: "[ㄱ-ㅎ가-힣]+",
    jp: "[\u3040-\u309F\u30A0-\u30FF]+",
    cn: "[\u4E00-\u9FBF]+",
    num: "[0-9]+",
    punct: "[（）.\&,;:-<>@%*，、。」]+"
    // punct: "[\(\).,\（\）\、·，;:」“”\"\'\-<>\&。]+"
  }

  function MultiLingual(params){
    this.containers = params.containers;
    this.configuration = params.configuration;

    this.init();
  }

  MultiLingual.prototype = {
    init: function(){
      this.finalRegex = this.composeRegex();

      for (var i = 0, len = this.containers.length; i < len; i++){
        var container = this.containers[i];

        this.recursiveChange(this.containers[0], container);
      }
    },

    recursiveChange: function(parent, dom){
      // debugger;
      if (dom.childNodes.length > 0) {
        for (var i = dom.childNodes.length - 1; i >= 0; i--) {
          this.recursiveChange(dom, dom.childNodes[i]);
        }
      } else {
        if (dom.nodeType === 3) {
          var configuration = this.configuration;

          var domStr = dom.textContent.replace(this.finalRegex, function(){
            for (var i = 1; i < arguments.length; i++) {
              if (arguments[i] != undefined) {
                var config = configuration[i - 1];
                var className;

                if (typeof config == "string"){
                  className = "ml-" + config;
                } else {
                  className = config.className;
                }

                return "" + arguments[i] + "";
              }
            }
          });

          var newDom = $.parseHTML(domStr);
          for (var i = 0; i < newDom.length; i++) {
            parent.insertBefore(newDom[i], dom);
          }

          dom.remove();
        }
      }
    },

    unescapeRegexStr: function(input) {
      return input.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">")
    },

    escapeRegexStr: function(str) {
      return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    computeCustomRegex: function (charset) {
      charset = this.escapeRegexStr(charset);

      var finalStr = "([" + charset + "]+)";
      return finalStr;
    },

    composeRegex: function(){
      var finalRegexStr = "(\?![^<>&]*>)";

      for (var i = 0, len = this.configuration.length; i < len; i++){
        var config = this.configuration[i];

        if (typeof config == "string"){ // ml-en 등 미리 정해진 프리셋의 경우
          finalRegexStr += "(" + regexs[config] + ")";
        } else {
          finalRegexStr += this.computeCustomRegex(config.charset);
        }

        if (i < this.configuration.length - 1) {
          finalRegexStr += "|";
        }
      }

      return new RegExp(finalRegexStr, "gm");
    }
  }

  $.fn.multilingual = function(params) {
    var multilingual = new MultiLingual({
      containers: this,
      configuration: params
    });

    return multilingual;
  };

}( jQuery ));<|endoftext|>


<commit_before>export const reverseString = (stringToReverse) => {
  let reversedString = '';
  for(var i = stringToReverse.length-1; i >=0; i--) {
    reversedString += stringToReverse.charAt(i);
  }
  return reversedString;
};
<commit_msg>Une troisième solution à l'exercice reverse-string d'Exercism dans la track Javascript.<commit_after>export const reverseString = (stringToReverse) => stringToReverse.split('').reverse().join('');
<|endoftext|>


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

  function histogram(args) {
    this.init = function(args) {
      this.args = args;

      raw_data_transformation(args);
      process_histogram(args);
      init(args);

      new MG.scale_factory(args)
        .namespace('x')
        .numericalDomainFromData()
        .numericalRange('bottom');

      var baselines = (args.baselines || []).map(function(d) {
        return d[args.y_accessor]
      });

      new MG.scale_factory(args)
        .namespace('y')
        .zeroBottom(true)
        .inflateDomain(true)
        .numericalDomainFromData(baselines)
        .numericalRange('left');

      x_axis(args);
      y_axis(args);

      this.mainPlot();
      this.markers();
      this.rollover();
      this.windowListeners();

      return this;
    };

    this.mainPlot = function() {
      const svg = mg_get_svg_child_of(args.target);

      //remove the old histogram, add new one
      svg.selectAll('.mg-histogram').remove();

      var g = svg.append('g')
        .attr('class', 'mg-histogram');

      var bar = g.selectAll('.mg-bar')
        .data(args.data[0])
        .enter().append('g')
        .attr('class', 'mg-bar')
        .attr('transform', function(d) {
          return "translate(" + args.scales.X(d[args.x_accessor]).toFixed(2) + "," + args.scales.Y(d[args.y_accessor]).toFixed(2) + ")";
        });

      //draw bars
      bar.append('rect')
        .attr('x', 1)
        .attr('width', function(d, i) {
          if (args.data[0].length === 1) {
            return (args.scalefns.xf(args.data[0][0]) - args.bar_margin).toFixed(0);
          } else if (i !== args.data[0].length - 1) {
            return (args.scalefns.xf(args.data[0][i + 1]) - args.scalefns.xf(d)).toFixed(0);
          } else {
            return (args.scalefns.xf(args.data[0][1]) - args.scalefns.xf(args.data[0][0])).toFixed(0);
          }
        })
        .attr('height', function(d) {
          if (d[args.y_accessor] === 0) {
            return 0;
          }

          return (args.height - args.bottom - args.buffer - args.scales.Y(d[args.y_accessor])).toFixed(2);
        });

      return this;
    };

    this.markers = function() {
      markers(args);
      return this;
    };

    this.rollover = function() {
      var svg = mg_get_svg_child_of(args.target);

      if (svg.selectAll('.mg-active-datapoint-container').nodes().length === 0) {
        mg_add_g(svg, 'mg-active-datapoint-container');
      }

      //remove the old rollovers if they already exist
      svg.selectAll('.mg-rollover-rect').remove();
      svg.selectAll('.mg-active-datapoint').remove();

      var g = svg.append('g')
        .attr('class', 'mg-rollover-rect');

      //draw rollover bars
      var bar = g.selectAll('.mg-bar')
        .data(args.data[0])
        .enter().append('g')
        .attr('class', function(d, i) {
          if (args.linked) {
            return 'mg-rollover-rects roll_' + i;
          } else {
            return 'mg-rollover-rects';
          }
        })
        .attr('transform', function(d) {
          return "translate(" + (args.scales.X(d[args.x_accessor])) + "," + 0 + ")";
        });

      bar.append('rect')
        .attr('x', 1)
        .attr('y', args.buffer + args.title_y_position)
        .attr('width', function(d, i) {
          //if data set is of length 1
          if (args.data[0].length === 1) {
            return (args.scalefns.xf(args.data[0][0]) - args.bar_margin).toFixed(0);
          } else if (i !== args.data[0].length - 1) {
            return (args.scalefns.xf(args.data[0][i + 1]) - args.scalefns.xf(d)).toFixed(0);
          } else {
            return (args.scalefns.xf(args.data[0][1]) - args.scalefns.xf(args.data[0][0])).toFixed(0);
          }
        })
        .attr('height', function(d) {
          return args.height;
        })
        .attr('opacity', 0)
        .on('mouseover', this.rolloverOn(args))
        .on('mouseout', this.rolloverOff(args))
        .on('mousemove', this.rolloverMove(args));

      return this;
    };

    this.rolloverOn = function(args) {
      var svg = mg_get_svg_child_of(args.target);

      return function(d, i) {
        svg.selectAll('text')
          .filter(function(g, j) {
            return d === g;
          })
          .attr('opacity', 0.3);

        var fmt = args.processed.xax_format || MG.time_format(args.utc_time, '%b %e, %Y');
        var num = format_rollover_number(args);

        svg.selectAll('.mg-bar rect')
          .filter(function(d, j) {
            return j === i;
          })
          .classed('active', true);

        //trigger mouseover on all matching bars
        if (args.linked && !MG.globals.link) {
          MG.globals.link = true;

          //trigger mouseover on matching bars in .linked charts
          d3.selectAll('.mg-rollover-rects.roll_' + i + ' rect')
            .each(function(d) { //use existing i
              d3.select(this).on('mouseover')(d, i);
            });
        }

        //update rollover text
        if (args.show_rollover_text) {
          var mo = mg_mouseover_text(args, { svg: svg });
          var row = mo.mouseover_row();
          row.text('\u259F  ').elem()
            .classed('hist-symbol', true);

          row.text(mg_format_x_mouseover(args, d)); // x
          row.text(mg_format_y_mouseover(args, d, args.time_series === false));
        }

        if (args.mouseover) {
          mg_setup_mouseover_container(svg, args);
          args.mouseover(d, i);
        }
      };
    };

    this.rolloverOff = function(args) {
      var svg = mg_get_svg_child_of(args.target);

      return function(d, i) {
        if (args.linked && MG.globals.link) {
          MG.globals.link = false;

          //trigger mouseout on matching bars in .linked charts
          d3.selectAll('.mg-rollover-rects.roll_' + i + ' rect')
            .each(function(d) { //use existing i
              d3.select(this).on('mouseout')(d, i);
            });
        }

        //reset active bar
        svg.selectAll('.mg-bar rect')
          .classed('active', false);

        //reset active data point text
        mg_clear_mouseover_container(svg);

        if (args.mouseout) {
          args.mouseout(d, i);
        }
      };
    };

    this.rolloverMove = function(args) {
      return function(d, i) {
        if (args.mousemove) {
          args.mousemove(d, i);
        }
      };
    };

    this.windowListeners = function() {
      mg_window_listeners(this.args);
      return this;
    };

    this.init(args);
  }

  var defaults = {
    binned: false,
    bins: null,
    processed_x_accessor: 'x',
    processed_y_accessor: 'y',
    processed_dx_accessor: 'dx',
    bar_margin: 1
  };

  MG.register('histogram', histogram, defaults);
}).call(this);
<commit_msg>Refactor: Update histogram.js to ES6 standards (issue #811)<commit_after>{
  function histogram(args) {
    this.init = (args) => {
      this.args = args;

      raw_data_transformation(args);
      process_histogram(args);
      init(args);

      new MG.scale_factory(args)
        .namespace('x')
        .numericalDomainFromData()
        .numericalRange('bottom');

      const baselines = (args.baselines || []).map(d => d[args.y_accessor]);

      new MG.scale_factory(args)
        .namespace('y')
        .zeroBottom(true)
        .inflateDomain(true)
        .numericalDomainFromData(baselines)
        .numericalRange('left');

      x_axis(args);
      y_axis(args);

      this.mainPlot();
      this.markers();
      this.rollover();
      this.windowListeners();

      return this;
    };

    this.mainPlot = () => {
      const svg = mg_get_svg_child_of(args.target);

      //remove the old histogram, add new one
      svg.selectAll('.mg-histogram').remove();

      const g = svg.append('g')
        .attr('class', 'mg-histogram');

      const bar = g.selectAll('.mg-bar')
        .data(args.data[0])
        .enter().append('g')
        .attr('class', 'mg-bar')
        .attr('transform', d => `translate(${args.scales.X(d[args.x_accessor]).toFixed(2)},${args.scales.Y(d[args.y_accessor]).toFixed(2)})`);

      //draw bars
      bar.append('rect')
        .attr('x', 1)
        .attr('width', (d, i) => {
          if (args.data[0].length === 1) {
            return (args.scalefns.xf(args.data[0][0]) - args.bar_margin).toFixed(0);
          } else if (i !== args.data[0].length - 1) {
            return (args.scalefns.xf(args.data[0][i + 1]) - args.scalefns.xf(d)).toFixed(0);
          } else {
            return (args.scalefns.xf(args.data[0][1]) - args.scalefns.xf(args.data[0][0])).toFixed(0);
          }
        })
        .attr('height', d => {
          if (d[args.y_accessor] === 0) {
            return 0;
          }

          return (args.height - args.bottom - args.buffer - args.scales.Y(d[args.y_accessor])).toFixed(2);
        });

      return this;
    };

    this.markers = () => {
      markers(args);
      return this;
    };

    this.rollover = () => {
      const svg = mg_get_svg_child_of(args.target);

      if (svg.selectAll('.mg-active-datapoint-container').nodes().length === 0) {
        mg_add_g(svg, 'mg-active-datapoint-container');
      }

      //remove the old rollovers if they already exist
      svg.selectAll('.mg-rollover-rect').remove();
      svg.selectAll('.mg-active-datapoint').remove();

      const g = svg.append('g')
        .attr('class', 'mg-rollover-rect');

      //draw rollover bars
      const bar = g.selectAll('.mg-bar')
        .data(args.data[0])
        .enter().append('g')
        .attr('class', (d, i) => {
          if (args.linked) {
            return `mg-rollover-rects roll_${i}`;
          } else {
            return 'mg-rollover-rects';
          }
        })
        .attr('transform', d => `translate(${args.scales.X(d[args.x_accessor])},${0})`);

      bar.append('rect')
        .attr('x', 1)
        .attr('y', args.buffer + args.title_y_position)
        .attr('width', (d, i) => {
          //if data set is of length 1
          if (args.data[0].length === 1) {
            return (args.scalefns.xf(args.data[0][0]) - args.bar_margin).toFixed(0);
          } else if (i !== args.data[0].length - 1) {
            return (args.scalefns.xf(args.data[0][i + 1]) - args.scalefns.xf(d)).toFixed(0);
          } else {
            return (args.scalefns.xf(args.data[0][1]) - args.scalefns.xf(args.data[0][0])).toFixed(0);
          }
        })
        .attr('height', d => args.height)
        .attr('opacity', 0)
        .on('mouseover', this.rolloverOn(args))
        .on('mouseout', this.rolloverOff(args))
        .on('mousemove', this.rolloverMove(args));

      return this;
    };

    this.rolloverOn = (args) => {
      const svg = mg_get_svg_child_of(args.target);

      return (d, i) => {
        svg.selectAll('text')
          .filter((g, j) => d === g)
          .attr('opacity', 0.3);

        const fmt = args.processed.xax_format || MG.time_format(args.utc_time, '%b %e, %Y');
        const num = format_rollover_number(args);

        svg.selectAll('.mg-bar rect')
          .filter((d, j) => j === i)
          .classed('active', true);

        //trigger mouseover on all matching bars
        if (args.linked && !MG.globals.link) {
          MG.globals.link = true;

          //trigger mouseover on matching bars in .linked charts
          d3.selectAll(`.mg-rollover-rects.roll_${i} rect`)
            .each(function(d) { //use existing i
              d3.select(this).on('mouseover')(d, i);
            });
        }

        //update rollover text
        if (args.show_rollover_text) {
          const mo = mg_mouseover_text(args, { svg });
          const row = mo.mouseover_row();
          row.text('\u259F  ').elem()
            .classed('hist-symbol', true);

          row.text(mg_format_x_mouseover(args, d)); // x
          row.text(mg_format_y_mouseover(args, d, args.time_series === false));
        }

        if (args.mouseover) {
          mg_setup_mouseover_container(svg, args);
          args.mouseover(d, i);
        }
      };
    };

    this.rolloverOff = (args) => {
      const svg = mg_get_svg_child_of(args.target);

      return (d, i) => {
        if (args.linked && MG.globals.link) {
          MG.globals.link = false;

          //trigger mouseout on matching bars in .linked charts
          d3.selectAll(`.mg-rollover-rects.roll_${i} rect`)
            .each(function(d) { //use existing i
              d3.select(this).on('mouseout')(d, i);
            });
        }

        //reset active bar
        svg.selectAll('.mg-bar rect')
          .classed('active', false);

        //reset active data point text
        mg_clear_mouseover_container(svg);

        if (args.mouseout) {
          args.mouseout(d, i);
        }
      };
    };

    this.rolloverMove = (args) => (d, i) => {
      if (args.mousemove) {
        args.mousemove(d, i);
      }
    };

    this.windowListeners = () => {
      mg_window_listeners(this.args);
      return this;
    };

    this.init(args);
  }

  const defaults = {
    binned: false,
    bins: null,
    processed_x_accessor: 'x',
    processed_y_accessor: 'y',
    processed_dx_accessor: 'dx',
    bar_margin: 1
  };

  MG.register('histogram', histogram, defaults);
}<|endoftext|>


<commit_before>require.config({
    paths: {
        d3: 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.1/d3.min'
    }
});

define(function(require) {
   var widget = require("widgets/js/widget");
   var utils = require("base/js/utils");

   var MG = require("/nbextensions/metricsgraphics/metricsgraphics.js");

   var MetricsGraphicsView = widget.DOMWidgetView.extend({
       render: function() {

           // Create the viewing frame.
           this.$el.css({
               overflow: 'hidden'
           }).attr('id', utils.uuid());

           this.once('displayed', function() {
               this.model.on('change:data', this._redraw, this);

               this.model.on('change:width', this._redraw, this);
               this.model.on('change:height', this._redraw, this);

               this.model.on('change:title', this._redraw, this);
               this.model.on('change:description', this._redraw, this);

               this.model.on('change:x_accessor', this._redraw, this);
               this.model.on('change:y_accessor', this._redraw, this);

               this.model.on('change:markers', this._redraw, this);
               this._redraw();
           });
       },

       _redraw: function() {
          var data = this.model.get('data');

          var width = this.model.get('width');
          var height = this.model.get('height');

          this.$el.width(width);
          this.$el.height(height);

          MG.data_graphic({
            title: "UFO Sightings",
            description: "Yearly UFO sightings from the year 1945 to 2010.",
            data: data,
            width: width,
            height: height,
            target: '#' + this.$el.attr('id'),
            x_accessor: 'year',
            y_accessor: 'sightings',
            markers: [{'year': 1964, 'label': '"The Creeping Terror" released'}]
          });
       }

   });

   return {
       MetricsGraphicsView: MetricsGraphicsView
   };
});
<commit_msg>Bring in components of the model selectively.<commit_after>require.config({
    paths: {
        d3: 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.1/d3.min'
    }
});

define(function(require) {
   var widget = require("widgets/js/widget");
   var utils = require("base/js/utils");

   var MG = require("/nbextensions/metricsgraphics/metricsgraphics.js");

   var MetricsGraphicsView = widget.DOMWidgetView.extend({
       render: function() {

           // Create the viewing frame.
           this.$el.css({
               overflow: 'hidden'
           }).attr('id', utils.uuid());

           this.once('displayed', function() {
               this.model.on('change:data', this._redraw, this);

               this.model.on('change:width', this._redraw, this);
               this.model.on('change:height', this._redraw, this);

               this.model.on('change:title', this._redraw, this);
               this.model.on('change:description', this._redraw, this);

               this.model.on('change:x_accessor', this._redraw, this);
               this.model.on('change:y_accessor', this._redraw, this);

               this.model.on('change:markers', this._redraw, this);
               this._redraw();
           });
       },

       _redraw: function() {

          var data = this.model.get('data');

          var width = this.model.get('width');
          var height = this.model.get('height');

          var description = this.model.get('description');

          var title = this.model.get('title');
          var x_accessor = this.model.get('x_accessor');
          var y_accessor = this.model.get('y_accessor');

          var markers = this.model.get('markers');

          this.$el.width(width);
          this.$el.height(height);

          MG.data_graphic({
            title: title,
            description: description,
            data: data,
            width: width,
            height: height,
            target: '#' + this.$el.attr('id'),
            x_accessor: x_accessor,
            y_accessor: y_accessor,
            markers: markers
          });
       }

   });

   return {
       MetricsGraphicsView: MetricsGraphicsView
   };
});
<|endoftext|>


<commit_before>// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.

var React = require('react');

var BASE_WIDTH = 400;
var BASE_HEIGHT = 200;

var Chart = React.createClass({

  propTypes: {
    key: React.PropTypes.bool,
    max: React.PropTypes.number,
    min: React.PropTypes.number,
    series: React.PropTypes.arrayOf(
      React.PropTypes.shape({
        label: React.PropTypes.string,
        values: React.PropTypes.arrayOf(
          React.PropTypes.arrayOf(React.PropTypes.number)),
        colorIndex: React.PropTypes.string
      })
    ).isRequired,
    threshold: React.PropTypes.number
  },

  getInitialState: function () {
    // analyze series data
    var minX = null;
    var maxX = null;
    var minY = null;
    var maxY = null;
    var maxValues = 0;
    this.props.series.forEach(function (item) {
      item.values.forEach(function (value) {
        var x = value[0];
        var y = value[1];
        if (null === minX) {
          minX = x;
          maxX = x;
          minY = y;
          maxY = y;
        } else {
          minX = Math.min(minX, x);
          maxX = Math.max(maxX, x);
          minY = Math.min(minY, y);
          maxY = Math.max(maxY, y);
        }
      });
      maxValues = Math.max(maxValues, item.values.length);
    });
    if (this.props.threshold) {
      minX = Math.min(minX, this.props.threshold);
      maxX = Math.max(maxX, this.props.threshold);
    }
    return {
      minX: minX,
      maxX: maxX,
      minY: this.props.min || minY,
      maxY: this.props.max || maxY,
      steps: maxValues
    };
  },

  _translateX: function (x) {
    return (x - this.state.minX) * (BASE_WIDTH) / (this.state.maxX - this.state.minX);
  },

  _translateY: function (y) {
    // leave room for line width since strokes are aligned to the center
    return Math.min(BASE_HEIGHT -
      ((y - this.state.minY) * (BASE_HEIGHT) / (this.state.maxY - this.state.minY)),
      BASE_HEIGHT - 1);
  },

  _coordinates: function (point) {
    return this._translateX(point[0]) + ',' + this._translateY(point[1]);
  },

  render: function() {
    var grid = [];
    var step = BASE_WIDTH / this.state.steps;
    //for (var i=0; i<=BASE_WIDTH; i = i + step) {
    //  grid.push(<path key={i} fill="none" d={"M" + i + ",0L" + i + "," + BASE_HEIGHT} />);
    //}
    //step = BASE_HEIGHT / 5;
    //for (i=BASE_HEIGHT; i>=0; i = i - step) {
    //  grid.push(<path key={100 + i} fill="none" d={"M0," + i + "L" + BASE_WIDTH + "," + i} />);
    //}

    var lines = {};
    var keys = {};
    var close = 'L' + BASE_WIDTH + ',' + BASE_HEIGHT + 'L0,' + BASE_HEIGHT + 'Z';

    this.props.series.forEach(function (item, index) {
      var commands = null;
      item.values.forEach(function (value) {
        if (null === commands) {
          commands = "M" + this._coordinates(value);
        } else {
          commands += "L" + this._coordinates(value);
        }
      }, this);
      lines[index] = (
        <g>
          <path fill="none" className={"chart__lines-line color-index-" + item.colorIndex} d={commands} />
          <path stroke="none" className={"chart__lines-area color-index-" + item.colorIndex} d={commands + close} />
        </g>
      );

      /*if (this.props.key) {

        var keyItemClasses = ["chart__key-item"];

        keys[index] = (

            <svg className={"chart__key-item-swatch"} viewBox="0 0 10 10">
              <path className={item.className} d="M 5 0 l 0 10" />
            </svg>
            {item.label}

        );
      }*/
    }, this);

    threshold = null;
    if (this.props.threshold) {
      commands = 'M' + this._coordinates([this.state.minX, this.props.threshold]) +
        'L' + this._coordinates([this.state.maxX, this.props.threshold]);
      threshold = (
        <g>
          <path className="chart__threshold" fill="none" d={commands} />
        </g>
      );
    }

    return (

        <svg className="chart__graphic" viewBox={"0 0 " + BASE_WIDTH + " " + BASE_HEIGHT}
          preserveAspectRatio="xMidYMid meet">
          <g className="chart__grid">{grid}</g>
          <g className="chart__lines">{lines}</g>
          {threshold}
        </svg>

          {keys}

    );
  }

});

module.exports = Chart;
<commit_msg>fix lint errors in Chart<commit_after>// (C) Copyright 2014 Hewlett-Packard Development Company, L.P.

var React = require('react');

var BASE_WIDTH = 400;
var BASE_HEIGHT = 200;

var Chart = React.createClass({

  propTypes: {
    key: React.PropTypes.bool,
    max: React.PropTypes.number,
    min: React.PropTypes.number,
    series: React.PropTypes.arrayOf(
      React.PropTypes.shape({
        label: React.PropTypes.string,
        values: React.PropTypes.arrayOf(
          React.PropTypes.arrayOf(React.PropTypes.number)),
        colorIndex: React.PropTypes.string
      })
    ).isRequired,
    threshold: React.PropTypes.number
  },

  getInitialState: function () {
    // analyze series data
    var minX = null;
    var maxX = null;
    var minY = null;
    var maxY = null;
    var maxValues = 0;
    this.props.series.forEach(function (item) {
      item.values.forEach(function (value) {
        var x = value[0];
        var y = value[1];
        if (null === minX) {
          minX = x;
          maxX = x;
          minY = y;
          maxY = y;
        } else {
          minX = Math.min(minX, x);
          maxX = Math.max(maxX, x);
          minY = Math.min(minY, y);
          maxY = Math.max(maxY, y);
        }
      });
      maxValues = Math.max(maxValues, item.values.length);
    });
    if (this.props.threshold) {
      minX = Math.min(minX, this.props.threshold);
      maxX = Math.max(maxX, this.props.threshold);
    }
    return {
      minX: minX,
      maxX: maxX,
      minY: this.props.min || minY,
      maxY: this.props.max || maxY,
      steps: maxValues
    };
  },

  _translateX: function (x) {
    return (x - this.state.minX) * (BASE_WIDTH) / (this.state.maxX - this.state.minX);
  },

  _translateY: function (y) {
    // leave room for line width since strokes are aligned to the center
    return Math.min(BASE_HEIGHT -
      ((y - this.state.minY) * (BASE_HEIGHT) / (this.state.maxY - this.state.minY)),
      BASE_HEIGHT - 1);
  },

  _coordinates: function (point) {
    return this._translateX(point[0]) + ',' + this._translateY(point[1]);
  },

  render: function() {
    var grid = [];
    //var step = BASE_WIDTH / this.state.steps;
    //for (var i=0; i<=BASE_WIDTH; i = i + step) {
    //  grid.push(<path key={i} fill="none" d={"M" + i + ",0L" + i + "," + BASE_HEIGHT} />);
    //}
    //step = BASE_HEIGHT / 5;
    //for (i=BASE_HEIGHT; i>=0; i = i - step) {
    //  grid.push(<path key={100 + i} fill="none" d={"M0," + i + "L" + BASE_WIDTH + "," + i} />);
    //}

    var lines = {};
    var keys = {};
    var close = 'L' + BASE_WIDTH + ',' + BASE_HEIGHT + 'L0,' + BASE_HEIGHT + 'Z';

    this.props.series.forEach(function (item, index) {
      var commands = null;
      item.values.forEach(function (value) {
        if (null === commands) {
          commands = "M" + this._coordinates(value);
        } else {
          commands += "L" + this._coordinates(value);
        }
      }, this);
      lines[index] = (
        <g>
          <path fill="none" className={"chart__lines-line color-index-" + item.colorIndex} d={commands} />
          <path stroke="none" className={"chart__lines-area color-index-" + item.colorIndex} d={commands + close} />
        </g>
      );

      /*if (this.props.key) {

        var keyItemClasses = ["chart__key-item"];

        keys[index] = (

            <svg className={"chart__key-item-swatch"} viewBox="0 0 10 10">
              <path className={item.className} d="M 5 0 l 0 10" />
            </svg>
            {item.label}

        );
      }*/
    }, this);

    var threshold = null;
    if (this.props.threshold) {
      var commands = 'M' + this._coordinates([this.state.minX, this.props.threshold]) +
        'L' + this._coordinates([this.state.maxX, this.props.threshold]);
      threshold = (
        <g>
          <path className="chart__threshold" fill="none" d={commands} />
        </g>
      );
    }

    return (

        <svg className="chart__graphic" viewBox={"0 0 " + BASE_WIDTH + " " + BASE_HEIGHT}
          preserveAspectRatio="xMidYMid meet">
          <g className="chart__grid">{grid}</g>
          <g className="chart__lines">{lines}</g>
          {threshold}
        </svg>

          {keys}

    );
  }

});

module.exports = Chart;
<|endoftext|>


<commit_before>Meteor.startup(function() {

  AccountsEntry.config({
    signupCode: null
  });

});
<commit_msg>Fix from Michael Hoeller<commit_after>Meteor.startup(function() {

  AccountsEntry.config({
    signupCode: null
  });
  Accounts.onCreateUser( function (options, user) {
        if (options.profile) user.profile = options.profile;
        user.username = options.email;
        return user;
    });
});
<|endoftext|>


<commit_before>// Github:    https://github.com/symposion/roll20-api-scripts/
// By:       Lucian Holland

var DynamicLightRecorder = DynamicLightRecorder || (function() {
    'use strict';

    var version = '0.2',
        schemaVersion = 0.2,

    checkInstall = function() {
        log('-=> DynamicLightRecorder v'+version+' <=-  ['+(new Date(lastUpdate*1000))+']');
        if( ! _.has(state,'DynamicLightRecorder') || state.DynamicLightRecorder.version !== schemaVersion) {
            log('  > Updating Schema to v'+schemaVersion+' <');
            switch(state.DynamicLightRecorder && state.DynamicLightRecorder.version) {
                case '0.1':
                    _.each(state.DynamicLightRecorder.tilePaths, function(tilePath) {
                        var tileToken = getObj('graphic', tilePath.tileId);
                        if (tileToken) {
                            tileToken.set('controlledby', tilePath.pathIds.join(','));
                        }
                    });
                    delete state.DynamicLightRecorder.tilePaths;
                    break;
                default:
                    state.DynamicLightRecorder = {
                        version: schemaVersion,
                        tileTemplates: {},
                        config: {
                        }
                    };
                    break;
            }
        }
    },

    handleInput = function(msg) {
       if (msg.type !== "api" ) {
            return;
        }
        var args = msg.content.split(/\s+--/);
        switch(args.shift()) {
            case '!dl-attach':
                attach(msg.selected, !_.isEmpty(args) && args.shift() === 'overwrite');
                break;
            case '!dl-dump':
                sendChat('DynamicLightRecorder', JSON.stringify(state.DynamicLightRecorder));
                break;
            case '!dl-wipe':
                sendChat('DynamicLightRecorder', 'Wiping all data');
                state.DynamicLightRecorder.tilePaths = {};
                state.DynamicLightRecorder.tileTemplates = {};
                break;
            case '!dump-obj':
                sendChat('', JSON.stringify(_.map(msg.selected, function(obj){ return getObj(obj._type, obj._id)})));
                break;
            default:
            //Do nothing
        }
    },

    attach = function(selection, overwrite) {

        if (!selection || _.isEmpty(selection) || selection.length < 2) {
            sendChat('DynamicLightRecorder', 'You must have one map tile and at least one path select to run attach');
            return;
        }

        var objects = _.map(selection, function(object) {
            return getObj(object._type, object._id);
        });

        var tiles = [];
        var paths = [];
        _.each(objects, function(object) {
            if(object.get('_type') === 'path') {
                paths.push(object);
            }
            else {
                tiles.push(object);
            }
        });

        if (_.isEmpty(tiles) || tiles.length !== 1) {
            sendChat('DynamicLightRecorder', 'You must have exactly one map tile to run attach');
            return;
        }

        var tile = tiles[0];
        if (tile.get('_subtype') !== 'token' || !tile.get('imgsrc') || tile.get('imgsrc').indexOf('marketplace') === -1 || tile.get('layer') !== 'map') {
            sendChat('DynamicLightRecorder', 'Selected tile must be from marketplace and must be on the map layer.');
            return;
        }

        if (state.DynamicLightRecorder.tileTemplates[tile.get('imgsrc')] && !overwrite) {
           sendChat('DynamicLightRecorder', 'Tile already has dynamic lighting paths recorded. Call with --overwrite to replace them');
           return;
        }

        var template = {
            top: tile.get('top'),
            left: tile.get('left'),
            width: tile.get('width'),
            height: tile.get('height'),
            flipv: tile.get('flipv'),
            fliph: tile.get('fliph'),
            rotation: tile.get('rotation'),
            paths: _.map(paths, function(path) {
                var savedPath = {
                    path: path.get('_path'),
                    offsetY: path.get('top') - tile.get('top'),
                    offsetX: path.get('left') - tile.get('left'),
                    width: path.get('width'),
                    height: path.get('height'),
                    layer: 'walls'
                };
                return savedPath;
            })
        };
        state.DynamicLightRecorder.tileTemplates[tile.get('imgsrc')] = template;

    },

    handleNewToken = function(token) {
        var template = state.DynamicLightRecorder.tileTemplates[token.get('imgsrc')];
        if (!template) {
            log('no template found')
            return;
        }

        drawTokenPaths(token, template);
    },

    handleTokenChange = function(token, previous) {
        var template = state.DynamicLightRecorder.tileTemplates[token.get('imgsrc')];
        if (template) {
            deleteTokenPaths(token);
            drawTokenPaths(token, template);
        }
    },

    drawTokenPaths = function(token, template) {
        log(token);
        var paths = makeWorkingTemplate(template, token)
            .logme()
            .flip()
            .logme()
            .rotate()
            .logme()
            .scale()
            .logme()
            .buildPaths();
        log(paths);
        token.set("controlledby", _.pluck(paths, 'id').join(','));
    },

    makeWorkingTemplate = function(template, token) {
        template = _.clone(template);
        template.paths = _.map(template.paths, function(path) {
            path = _.clone(path);
            path.points = JSON.parse(path.path);
            return path;
        });

        template.flip = function() {
            var fliph = token.get('fliph'), flipv = token.get('flipv');
            fliph = (fliph !== this.fliph);
            flipv = (flipv !== this.flipv);
            if (fliph || flipv) {
                this.paths = _.map(this.paths, function(path) {
                    path.points = _.map(path.points, function(point) {
                        return [point[0],
                                fliph ? path.width - point[1] : point[1],
                                flipv ? path.height - point[2] : point[2]
                                ];
                    })
                    path.offsetX = fliph ? 0 - path.offsetX : path.offsetX;
                    path.offsetY = flipv ? 0 - path.offsetY : path.offsetY;
                    return path;
                }.bind(this));
            }
            return this;
        };

        template.rotate = function() {
            'use strict';
            var angle = token.get('rotation');
            angle -= this.rotation;
            if (angle % 360 == 0) return this;
            var tokenCentre = [token.get('left'), token.get('top')];

            _.each(this.paths, function(path) {

                    var pointsCentre = [path.width/2, path.height/2];

                    var bounds = {
                        xMax: 0,
                        yMax: 0,
                        xMin:Infinity,
                        yMin:Infinity
                    };

                    path.points = _.map(path.points, function(point) {
                            var result = rotatePoint(_.rest(point, 1), pointsCentre, angle);
                            bounds.xMax = Math.max(bounds.xMax, result[0]);
                            bounds.yMax = Math.max(bounds.yMax, result[1]);
                            bounds.xMin = Math.min(bounds.xMin, result[0]);
                            bounds.yMin = Math.min(bounds.yMin, result[1]);
                            result.unshift(point[0]);
                            return result;
                        });

                    _.each(path.points, function(point) {
                            point[1] -= bounds.xMin;
                            point[2] -= bounds.yMin;
                        });

                    path.width = bounds.xMax - bounds.xMin;
                    path.height = bounds.yMax - bounds.yMin;

                    //The bounding box has changed shape, which skews the centre
                    //away from where it would be if we'd just rotated the whole
                    //box as was. Allow for this offset.
                    var newCentreXOffset = (path.width/2 + bounds.xMin)  - pointsCentre[0];
                    var newCentreYOffset = (path.height/2 + bounds.yMin) - pointsCentre[1];

                    var oldCentreRotated = rotatePoint([path.offsetX, path.offsetY], [0,0], angle);

                    path.offsetX = oldCentreRotated[0] + newCentreXOffset;
                    path.offsetY = oldCentreRotated[1] + newCentreYOffset;
                });
            return this;
        };

        template.scale = function() {
            var scaleX = token.get('width') / this.width;
            var scaleY = token.get('height') / this.height;
            _.each(this.paths, function(path) {
                path.scaleX = scaleX;
                path.scaleY = scaleY;
                path.offsetX *= scaleX;
                path.offsetY *= scaleY;
            });
            return this;
        };

        template.buildPaths = function() {
            return _.map(this.paths, function(templatePath) {
                var attributes = _.clone(templatePath);
                attributes.path = JSON.stringify(templatePath.points);
                attributes.pageid = token.get('_pageid');
                attributes.left = token.get('left') + attributes.offsetX;
                attributes.top = token.get('top') + attributes.offsetY;
                return createObj('path', attributes);
            });
        };

        template.logme = function() {
            log(this);
            return this;
        };

        return template;
    },

    rotatePoint = function(point, centre, angle) {
        angle = angle % 360;
        var s = Math.sin(angle * Math.PI / 180.0);
        var c = Math.cos(angle * Math.PI / 180.0);
        // translate point back to origin:
        var x = point[0] - centre[0];
        var y = point[1] - centre[1];
        // rotate point
        var xnew = (x * c) - (y * s);
        var ynew = (x * s) + (y * c);

        // translate point back:
        x = xnew + centre[0];
        y = ynew + centre[1];
        return [x,y];
    },

    handleDeleteToken = function(token) {
        deleteTokenPaths(token);
    },

    deleteTokenPaths = function(token) {
         log('deleting paths for token ' + token.id);
        var paths = getPathsForToken(token);
        _.invoke(_.compact(paths), 'remove');
    },

    getPathsForToken = function(token) {
        var pathIds = token.get('controlledby').split(',');

        var paths = _.map(pathIds, function(pathId) {
            var path = getObj('path', pathId);
            if (!path) {
                log('Warning, path with id [' + pathId + '] that should have been attached to token ' + JSON.stringify(token) + ' was not present.');
            }
            return path;
        });
        return paths;
    },

    registerEventHandlers = function() {
        on('chat:message', handleInput);
        on('change:token', handleTokenChange);
        on('add:token', handleNewToken);
        on('destroy:graphic', handleDeleteToken);
    };

    return {
        RegisterEventHandlers: registerEventHandlers,
        CheckInstall: checkInstall
    };
}());

on("ready",function(){
    'use strict';

        DynamicLightRecorder.CheckInstall();
        DynamicLightRecorder.RegisterEventHandlers();
});
<commit_msg>Update to version 0.3, now supports doors!<commit_after>// Github:    https://github.com/symposion/roll20-api-scripts/
// By:       Lucian Holland

var DynamicLightRecorder = DynamicLightRecorder || (function() {
    'use strict';

    var version = '0.3',
        schemaVersion = 0.3,
        clearURL = 'https://s3.amazonaws.com/files.d20.io/images/4277467/iQYjFOsYC5JsuOPUCI9RGA/thumb.png?1401938659',

    checkInstall = function() {
        log('-=> DynamicLightRecorder v'+version);
        if( ! _.has(state,'DynamicLightRecorder') || state.DynamicLightRecorder.version !== schemaVersion) {
            log('  > Updating Schema to v'+schemaVersion+' <');
            switch(state.DynamicLightRecorder && state.DynamicLightRecorder.version) {
                case 0.1:
                    _.each(state.DynamicLightRecorder.tilePaths, function(tilePath) {
                        var tileToken = getObj('graphic', tilePath.tileId);
                        if (tileToken) {
                            var controlInfo = _.reduce(tilePath.pathIds, function(controlInfo, pathId) {
                                var path = getObj('path', pathId);
                                if (path && path !== null) {
                                    controlInfo.dlPaths.push(path);
                                }
                            }, { dlPaths: [], doorControl: null});
                            saveControlInfo(tileToken, controlInfo);
                        }
                    });
                    delete state.DynamicLightRecorder.tilePaths;
                case 0.2:
                    state.DynamicLightRecorder.doorControls = {};
                    _.chain(state.DynamicLightRecorder.tileTemplates)
                        .keys()
                        .map(function(imgsrc) {
                            return findObjs({_type: 'graphic', imgsrc:imgsrc, layer:'map', _subtype:'token'});
                        })
                        .tap(LHU.logTap)
                        .flatten()
                        .tap(LHU.logTap)
                        .each(function(graphic) {
                            var cb = graphic.get('controlledby');
                            log("controlledby: " + cb)
                            if (cb && !_.isEmpty(cb)) {
                                var paths = _.chain(cb.split(","))
                                            .map(function(pathId) {
                                                return getObj('path', pathId);
                                            })
                                            .compact()
                                            .tap(LHU.logTap)
                                            .value();
                                if (!_.isEmpty(paths)) {
                                    saveControlInfo(graphic, { dlPaths: paths, doorControl: null});
                                }
                            }
                        });
                    state.DynamicLightRecorder.version = 0.3;
                    break;
                default:
                    log('making state object');
                    state.DynamicLightRecorder = {
                        version: schemaVersion,
                        doorControls: {},
                        tileTemplates: {},
                        config: {
                        }
                    };
                    break;
            }
        }
    },

    handleInput = function(msg) {
       if (msg.type !== "api" ) {
            return;
        }
        var args = msg.content.split(/\s+--/);
        switch(args.shift()) {
            case '!dl-attach':
                attach(msg.selected, !_.isEmpty(args) && args.shift() === 'overwrite');
                break;
            case '!dl-door':
                makeDoors(msg.selected);
                break;
            case '!dl-dump':
                sendChat('DynamicLightRecorder', JSON.stringify(state.DynamicLightRecorder));
                break;
            case '!dl-wipe':
                sendChat('DynamicLightRecorder', 'Wiping all data');
                state.DynamicLightRecorder.tilePaths = {};
                state.DynamicLightRecorder.tileTemplates = {};
                state.DynamicLightRecorder.doorControls = {};
                break;
            case '!dump-obj':
                sendChat('', JSON.stringify(_.map(msg.selected, function(obj){ return getObj(obj._type, obj._id)})));
                break;
            default:
            //Do nothing
        }
    },

    makeDoors = function(selection) {
        if (!selection || _.isEmpty(selection)) {
            sendChat('DynamicLightRecord', 'You must have at least one token selected to run !dl-door');
            return;
        }

        _.each(selection, function(object) {
            var object = getObj(object._type, object._id);
            log(object);
            if(object.get('_subtype') === 'token') {
               makeDoor(object);
            }
        });

    },

    makeDoor = function(token) {
        var tokenWidth = token.get('width');
        var dlLineWidth = tokenWidth + 4;
        var centreX = token.get('left');
        var centreY = token.get('top');
        var left = centreX - tokenWidth / 2;

        token.set('layer', 'map');
        var dlPath = createObj('path', {
            pageid: token.get('_pageid'),
            layer: 'walls',
            stroke_width: 1,
            top: centreY,
            left: centreX,
            width: dlLineWidth,
            height: 1,
            path: '[["M",0,0],["L",' + dlLineWidth + ',0]]'
            });
        buildTemplate(token, [dlPath], true);
    },

    attach = function(selection, overwrite) {

        if (!selection || _.isEmpty(selection) || selection.length < 2) {
            sendChat('DynamicLightRecorder', 'You must have one map tile and at least one path select to run attach');
            return;
        }

        var objects = _.map(selection, function(object) {
            return getObj(object._type, object._id);
        });

        var tiles = [];
        var paths = [];
        _.each(objects, function(object) {
            if(object.get('_type') === 'path') {
                paths.push(object);
            }
            else {
                tiles.push(object);
            }
        });

        if (_.isEmpty(tiles) || tiles.length !== 1) {
            sendChat('DynamicLightRecorder', 'You must have exactly one map tile to run attach');
            return;
        }

        var tile = tiles[0];
        if (tile.get('_subtype') !== 'token' || !tile.get('imgsrc') || tile.get('imgsrc').indexOf('marketplace') === -1 || tile.get('layer') !== 'map') {
            sendChat('DynamicLightRecorder', 'Selected tile must be from marketplace and must be on the map layer.');
            return;
        }

        if (state.DynamicLightRecorder.tileTemplates[tile.get('imgsrc')] && !overwrite) {
           sendChat('DynamicLightRecorder', 'Tile already has dynamic lighting paths recorded. Call with --overwrite to replace them');
           return;
        }

        buildTemplate(tile, paths, false);
        sendChat("DynamicLightRecorder", "DL paths successfully recorded for map tile");
    },

    buildTemplate = function(tile, paths, isDoor) {
        log("Building new DL template for " + isDoor ? "door" : "tile");
        log(tile);
        log("with paths");
        log(paths);
         var template = {
            isDoor: isDoor,
            top: tile.get('top'),
            left: tile.get('left'),
            width: tile.get('width'),
            height: tile.get('height'),
            flipv: tile.get('flipv'),
            fliph: tile.get('fliph'),
            rotation: tile.get('rotation'),
            paths: _.map(paths, function(path) {
                var savedPath = {
                    path: path.get('_path'),
                    offsetY: path.get('top') - tile.get('top'),
                    offsetX: path.get('left') - tile.get('left'),
                    width: path.get('width'),
                    height: path.get('height'),
                    stroke_width: 1,
                    layer: 'walls'
                };
                path.set('layer', 'walls');
                path.set('stroke_width', 1);
                return savedPath;
            })
        };

        state.DynamicLightRecorder.tileTemplates[tile.get('imgsrc')] = template;
        saveTokenPaths(tile, paths);
        if (isDoor) {
            attachDoorControl(tile, template);
        }
    },

    attachDoorControl = function(doorToken, template) {
        var tokenWidth = doorToken.get('width');
        var tokenHeight = doorToken.get('height');
        var centreX = doorToken.get('left');
        var centreY = doorToken.get('top');
        var hingeX = centreX - tokenWidth / 2;
        var hingeY = centreY;
        var fliph = (template.fliph !== doorToken.get('fliph'));
        var flipv = (template.flipv !== doorToken.get('flipv'));
        var rotation = doorToken.get('rotation') - template.rotation;

        if (fliph || flipv) {
            hingeX = fliph ? tokenWidth - hingeX : hingeX;
            hingeY = fliph ? tokenHeight - hingeY : hingeY;
        }

        if (rotation % 360 != 0) {
            var newHinge = rotatePoint([hingeX, hingeY], [centreX, centreY], rotation);
            hingeX = newHinge[0];
            hingeY = newHinge[1];
        }

        var control = createObj('graphic', {
            imgsrc: clearURL,
            subtype: 'token',
            pageid: doorToken.get('_pageid'),
            layer: 'objects',
            playersedit_name: false,
            playersedit_bar1: false,
            playersedit_bar2: false,
            playersedit_bar3: false,
            aura1_radius: 0.1,
            rotation:rotation,
            isdrawing:1,
            top:hingeY,
            left: hingeX,
            width: 140,
            height: 140
        });
        var controlInfo = getTokenControlInfo(doorToken);
        controlInfo.doorControl = control;
        saveControlInfo(doorToken, controlInfo);
        state.DynamicLightRecorder.doorControls[control.id] = doorToken.id;
    },

    handleNewToken = function(token) {
        var template = state.DynamicLightRecorder.tileTemplates[token.get('imgsrc')];
        if (!template) {
            log('no template found')
            return;
        }

        drawTokenPaths(token, template);
        if (template.isDoor) {
            attachDoorControl(token, template);
        }
    },

    handleTokenChange = function(token, previous) {
        var template = state.DynamicLightRecorder.tileTemplates[token.get('imgsrc')];
        if (template) {
            deleteTokenPaths(token, function() {
                deleteDoorControls(token);
                drawTokenPaths(token, template);
                if(template.isDoor) {
                    attachDoorControl(token, template)
                }
            });
        }

        //Check if the changed token is a door control - do we have a door
        //token keyed off its id in our lookup
        var doorId = state.DynamicLightRecorder.doorControls[token.id];
        var door = getObj('graphic', doorId);
        if (door) {
            var rotation = token.get('rotation') - previous.rotation;
            log("Checking door control rotation " + rotation);
            if (rotation % 360 !== 0) {
                //The control is centred on the hinge of the door
                var hinge = [token.get('left'), token.get('top')];
                var doorCentre = [door.get('left'), door.get('top')];
                var offset = rotatePoint(doorCentre, hinge, rotation);

                door.set('left', offset[0]);
                door.set('top', offset[1]);
                door.set('rotation', door.get('rotation') + rotation);
                //Now redraw the door and associate DL paths
                handleTokenChange(door, {});
            }
            //Reset attempts to move the door control away from the door
            else if (token.get('top') !== previous.top || token.get('left') !== previous.left
                    || token.get('width') !== previous.width || token.get('height') !== previous.height) {
                token.set('top', previous.top);
                token.set('left', previous.left);
                token.set('width', previous.width);
                token.set('height', previous.height);
            }
        }
    },

    drawTokenPaths = function(token, template) {
        log(token);
        var paths = makeWorkingTemplate(template, token)
            .flip()
            .rotate()
            .scale()
            .buildPaths();
        saveTokenPaths(token, paths);
    },

    makeWorkingTemplate = function(template, token) {
        template = _.clone(template);
        template.paths = _.map(template.paths, function(path) {
            path = _.clone(path);
            path.points = JSON.parse(path.path);
            return path;
        });

        template.flip = function() {
            var fliph = token.get('fliph'), flipv = token.get('flipv');
            fliph = (fliph !== this.fliph);
            flipv = (flipv !== this.flipv);
            if (fliph || flipv) {
                this.paths = _.map(this.paths, function(path) {
                    path.points = _.map(path.points, function(point) {
                        return [point[0],
                                fliph ? path.width - point[1] : point[1],
                                flipv ? path.height - point[2] : point[2]
                                ];
                    })
                    path.offsetX = fliph ? 0 - path.offsetX : path.offsetX;
                    path.offsetY = flipv ? 0 - path.offsetY : path.offsetY;
                    return path;
                }.bind(this));
            }
            return this;
        };

        template.rotate = function() {
            'use strict';
            var angle = token.get('rotation');
            angle -= this.rotation;
            if (angle % 360 == 0) return this;
            var tokenCentre = [token.get('left'), token.get('top')];

            _.each(this.paths, function(path) {

                    var pointsCentre = [path.width/2, path.height/2];

                    var bounds = {
                        xMax: 0,
                        yMax: 0,
                        xMin:Infinity,
                        yMin:Infinity
                    };

                    path.points = _.map(path.points, function(point) {
                            var result = rotatePoint(_.rest(point, 1), pointsCentre, angle);
                            bounds.xMax = Math.max(bounds.xMax, result[0]);
                            bounds.yMax = Math.max(bounds.yMax, result[1]);
                            bounds.xMin = Math.min(bounds.xMin, result[0]);
                            bounds.yMin = Math.min(bounds.yMin, result[1]);
                            result.unshift(point[0]);
                            return result;
                        });

                    _.each(path.points, function(point) {
                            point[1] -= bounds.xMin;
                            point[2] -= bounds.yMin;
                        });

                    path.width = bounds.xMax - bounds.xMin;
                    path.height = bounds.yMax - bounds.yMin;

                    //The bounding box has changed shape, which skews the centre
                    //away from where it would be if we'd just rotated the whole
                    //box as was. Allow for this offset.
                    var newCentreXOffset = (path.width/2 + bounds.xMin)  - pointsCentre[0];
                    var newCentreYOffset = (path.height/2 + bounds.yMin) - pointsCentre[1];

                    var oldCentreRotated = rotatePoint([path.offsetX, path.offsetY], [0,0], angle);

                    path.offsetX = oldCentreRotated[0] + newCentreXOffset;
                    path.offsetY = oldCentreRotated[1] + newCentreYOffset;
                });
            return this;
        };

        template.scale = function() {
            var scaleX = token.get('width') / this.width;
            var scaleY = token.get('height') / this.height;
            _.each(this.paths, function(path) {
                path.scaleX = scaleX;
                path.scaleY = scaleY;
                path.offsetX *= scaleX;
                path.offsetY *= scaleY;
            });
            return this;
        };

        template.buildPaths = function() {
            return _.map(this.paths, function(templatePath) {
                var attributes = _.clone(templatePath);
                attributes.path = JSON.stringify(templatePath.points);
                attributes.pageid = token.get('_pageid');
                attributes.left = token.get('left') + attributes.offsetX;
                attributes.top = token.get('top') + attributes.offsetY;
                return createObj('path', attributes);
            });
        };

        template.logme = function() {
            log(this);
            return this;
        };

        return template;
    },

    rotatePoint = function(point, centre, angle) {
        angle = angle % 360;
        var s = Math.sin(angle * Math.PI / 180.0);
        var c = Math.cos(angle * Math.PI / 180.0);
        // translate point back to origin:
        var x = point[0] - centre[0];
        var y = point[1] - centre[1];
        // rotate point
        var xnew = (x * c) - (y * s);
        var ynew = (x * s) + (y * c);

        // translate point back:
        x = xnew + centre[0];
        y = ynew + centre[1];
        return [x,y];
    },

    handleDeleteToken = function(token) {
        deleteTokenPaths(token);
        deleteDoorControls(token);
    },

    getTokenControlInfo = function(token) {
        var controlInfoString = token.get('controlledby');
        var controlInfo = { dlPaths: [], doorControl: null};
        if (controlInfoString && !_.isEmpty(controlInfoString)) {
            var parsedControlInfo = JSON.parse(controlInfoString);
            controlInfo.dlPaths = _.chain(parsedControlInfo.dlPaths)
                .map(function(pathId) {
                    var path = getObj('path', pathId);
                    if (!path) {
                        log('Warning, path with id [' + pathId + '] that should have been attached to token ' + JSON.stringify(token) + ' was not present.');
                    }
                    return path;
                })
                .compact()
                .value();

            if (parsedControlInfo.doorControl !== null) {
                var control = getObj('graphic', parsedControlInfo.doorControl);

                if (!control) {
                    log('Warning, control with id [' + parsedControlInfo.doorControl + '] that should have been attached to token ' + JSON.stringify(token) + ' was not present.');
                }
                else {
                    controlInfo.doorControl = control
                }
            }
        }

        //Overwrite whatever is in the field in case we've pruned delete paths
        //or the controlInfo was missing.
        saveControlInfo(token, controlInfo);
       return controlInfo;
    },

    saveTokenPaths = function(token, paths) {
        var controlInfo = getTokenControlInfo(token);
        controlInfo.dlPaths = _.compact(paths);
        saveControlInfo(token, controlInfo);
    },

    saveControlInfo = function(token, controlInfo) {
        var json = JSON.stringify(controlInfo, function(key, value) {
            if (key === '') {
                //root object
                return value;
            }
            if (_.isArray(value)) {
                return _.pluck(value, 'id');
            }
            if (typeof value === 'object' && value !== null) {
                return value._id;
            }
            return value;
        });
        token.set("controlledby", json);
    },

    deleteDoorControls = function(token) {
         var controlInfo = getTokenControlInfo(token);
         if (controlInfo.doorControl && !_.isEmpty(controlInfo.doorControl)) {
            controlInfo.doorControl.remove();
            controlInfo.doorControl = null;
         }
        saveControlInfo(token, controlInfo);
    },

    deleteTokenPaths = function(token, callbackBeforeRemovingFromCanvas) {
        log('deleting paths for token ' + token.id);
        var controlInfo = getTokenControlInfo(token);
        var pathsToDelete =  controlInfo.dlPaths;
        controlInfo.dlPaths = [];
        saveControlInfo(token, controlInfo);
        if (typeof callbackBeforeRemovingFromCanvas === 'function') {
            callbackBeforeRemovingFromCanvas();
        }
        _.invoke(pathsToDelete, 'remove');
    },

    registerEventHandlers = function() {
        on('chat:message', handleInput);
        on('change:token', handleTokenChange);
        on('add:token', handleNewToken);
        on('destroy:graphic', handleDeleteToken);
    };

    return {
        RegisterEventHandlers: registerEventHandlers,
        CheckInstall: checkInstall
    };
}());

on("ready",function(){
    'use strict';

        DynamicLightRecorder.CheckInstall();
        DynamicLightRecorder.RegisterEventHandlers();
});

<|endoftext|>


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

/* @flow strict */

import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';

import {
  PrimaryExample,
  SecondaryExample,
  DestructiveExample,
  LinkExample,
  FeaturedExample,
  OutlineExample,
  ComponentButtonPrimaryExample,
  ComponentButtonSecondaryExample,
  ComponentButtonDestructiveExample,
  ComponentButtonLinkExample,
  ComponentButtonLinkWithPaddingExample,
  ComponentButtonFeaturedExample,
  ComponentButtonOutlineExample,
  MixedExample,
  AnchorTagsExample,
} from './examples';

storiesOf('bpk-component-button', () => module)
  .add('BpkButton (Primary)', () => (
    <PrimaryExample onClick={action('Primary button clicked')} />
  ))
  .add('BpkButton (Secondary)', () => (
    <SecondaryExample onClick={action('Secondary button clicked')} />
  ))
  .add('BpkButton (Destructive)', () => (
    <DestructiveExample onClick={action('Destructive button clicked')} />
  ))
  .add('BpkButton (Link button)', () => (
    <LinkExample onClick={action('Link button clicked')} />
  ))
  .add('BpkButton (Featured)', () => (
    <FeaturedExample onClick={action('Featured button clicked')} />
  ))
  .add('BpkButton (Outline)', () => (
    <OutlineExample onClick={action('Outline button clicked')} />
  ))
  .add('Primary', () => (
    <ComponentButtonPrimaryExample onClick={action('Primary button clicked')} />
  ))
  .add('Secondary', () => (
    <ComponentButtonSecondaryExample
      onClick={action('Secondary button clicked')}
    />
  ))
  .add('Destructive', () => (
    <ComponentButtonDestructiveExample
      onClick={action('Destructive button clicked')}
    />
  ))
  .add('Link button', () => (
    <ComponentButtonLinkExample onClick={action('Link button clicked')} />
  ))
  .add('Link button with padding', () => (
    <ComponentButtonLinkWithPaddingExample
      onClick={action('Link button clicked')}
    />
  ))
  .add('Featured', () => (
    <ComponentButtonFeaturedExample
      onClick={action('Featured button clicked')}
    />
  ))
  .add('Outline', () => (
    <ComponentButtonOutlineExample onClick={action('Outline button clicked')} />
  ))
  .add('Mixture', () => <MixedExample onClick={action('Button clicked')} />)
  .add('Anchor tags', () => (
    <AnchorTagsExample onClick={action('Anchor button clicked')} />
  ));
<commit_msg>Fix licence<commit_after>/*
 * Backpack - Skyscanner's Design System
 *
 * Copyright 2016-2021 Skyscanner Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* @flow strict */

import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';

import {
  PrimaryExample,
  SecondaryExample,
  DestructiveExample,
  LinkExample,
  FeaturedExample,
  OutlineExample,
  ComponentButtonPrimaryExample,
  ComponentButtonSecondaryExample,
  ComponentButtonDestructiveExample,
  ComponentButtonLinkExample,
  ComponentButtonLinkWithPaddingExample,
  ComponentButtonFeaturedExample,
  ComponentButtonOutlineExample,
  MixedExample,
  AnchorTagsExample,
} from './examples';

storiesOf('bpk-component-button', () => module)
  .add('BpkButton (Primary)', () => (
    <PrimaryExample onClick={action('Primary button clicked')} />
  ))
  .add('BpkButton (Secondary)', () => (
    <SecondaryExample onClick={action('Secondary button clicked')} />
  ))
  .add('BpkButton (Destructive)', () => (
    <DestructiveExample onClick={action('Destructive button clicked')} />
  ))
  .add('BpkButton (Link button)', () => (
    <LinkExample onClick={action('Link button clicked')} />
  ))
  .add('BpkButton (Featured)', () => (
    <FeaturedExample onClick={action('Featured button clicked')} />
  ))
  .add('BpkButton (Outline)', () => (
    <OutlineExample onClick={action('Outline button clicked')} />
  ))
  .add('Primary', () => (
    <ComponentButtonPrimaryExample onClick={action('Primary button clicked')} />
  ))
  .add('Secondary', () => (
    <ComponentButtonSecondaryExample
      onClick={action('Secondary button clicked')}
    />
  ))
  .add('Destructive', () => (
    <ComponentButtonDestructiveExample
      onClick={action('Destructive button clicked')}
    />
  ))
  .add('Link button', () => (
    <ComponentButtonLinkExample onClick={action('Link button clicked')} />
  ))
  .add('Link button with padding', () => (
    <ComponentButtonLinkWithPaddingExample
      onClick={action('Link button clicked')}
    />
  ))
  .add('Featured', () => (
    <ComponentButtonFeaturedExample
      onClick={action('Featured button clicked')}
    />
  ))
  .add('Outline', () => (
    <ComponentButtonOutlineExample onClick={action('Outline button clicked')} />
  ))
  .add('Mixture', () => <MixedExample onClick={action('Button clicked')} />)
  .add('Anchor tags', () => (
    <AnchorTagsExample onClick={action('Anchor button clicked')} />
  ));
<|endoftext|>