<commit_before>'use strict';
import fs from 'fs';
import path from 'path';

import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import SystemBellPlugin from 'system-bell-webpack-plugin';
import Clean from 'clean-webpack-plugin';
import merge from 'webpack-merge';
import React from 'react';
import ReactDOM from 'react-dom/server';
import MTRC from 'markdown-to-react-components';

import App from './demo/App.jsx';
import pkg from './package.json';

const TARGET = process.env.npm_lifecycle_event;
const ROOT_PATH = __dirname;
const config = {
  paths: {
    dist: path.join(ROOT_PATH, 'dist'),
    src: path.join(ROOT_PATH, 'src'),
    demo: path.join(ROOT_PATH, 'demo'),
    tests: path.join(ROOT_PATH, 'tests')
  },
  filename: 'boilerplate',
  library: 'Boilerplate'
};
const CSS_PATHS = [
  config.paths.demo,
  path.join(ROOT_PATH, 'style.css'),
  path.join(ROOT_PATH, 'node_modules/purecss'),
  path.join(ROOT_PATH, 'node_modules/highlight.js/styles/github.css'),
  path.join(ROOT_PATH, 'node_modules/react-ghfork/gh-fork-ribbon.ie.css'),
  path.join(ROOT_PATH, 'node_modules/react-ghfork/gh-fork-ribbon.css')
];

process.env.BABEL_ENV = TARGET;

const demoCommon = {
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.png', '.jpg']
  },
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        include: [
          config.paths.demo,
          config.paths.src
        ]
      }
    ],
    loaders: [
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
        include: config.paths.demo
      },
      {
        test: /\.jpg$/,
        loader: 'file',
        include: config.paths.demo
      },
      {
        test: /\.json$/,
        loader: 'json',
        include: path.join(ROOT_PATH, 'package.json')
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'start') {
  module.exports = merge(demoCommon, {
    devtool: 'eval-source-map',
    entry: config.paths.demo,
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('development')
      }),
      new HtmlWebpackPlugin({
        title: pkg.name + ' - ' + pkg.description,
        templateContent: renderJSX
      }),
      new webpack.HotModuleReplacementPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loaders: ['style', 'css'],
          include: CSS_PATHS
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.demo,
            config.paths.src
          ]
        }
      ]
    },
    devServer: {
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,
      host: process.env.HOST,
      port: process.env.PORT,
      stats: 'errors-only'
    }
  });
}

if (TARGET === 'gh-pages' || TARGET === 'deploy-gh-pages') {
  module.exports = merge(demoCommon, {
    entry: {
      app: config.paths.demo,
      vendors: [
        'react'
      ]
    },
    output: {
      path: './gh-pages',
      filename: 'bundle.[chunkhash].js'
    },
    plugins: [
      new Clean(['gh-pages']),
      new ExtractTextPlugin('styles.[chunkhash].css'),
      new webpack.DefinePlugin({
          // This has effect on the react lib size
        'process.env.NODE_ENV': JSON.stringify('production')
      }),
      new HtmlWebpackPlugin({
        title: pkg.name + ' - ' + pkg.description,
        templateContent: renderJSX.bind(null, ReactDOM.renderToString(<App />))
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      }),
      new webpack.optimize.CommonsChunkPlugin({
        names: ['vendors', 'manifest']
      }),
      new webpack.NamedModulesPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css'),
          include: CSS_PATHS
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.demo,
            config.paths.src
          ]
        }
      ]
    }
  });
}

// !TARGET === prepush hook for test
if (TARGET === 'test' || TARGET === 'tdd' || !TARGET) {
  module.exports = merge(demoCommon, {
    module: {
      preLoaders: [
        {
          test: /\.jsx?$/,
          loaders: ['eslint'],
          include: [
            config.paths.tests
          ]
        }
      ],
      loaders: [
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.src,
            config.paths.tests
          ]
        }
      ]
    }
  })
}

const distCommon = {
  devtool: 'source-map',
  output: {
    path: config.paths.dist,
    libraryTarget: 'umd',
    library: config.library
  },
  entry: config.paths.src,
  externals: {
    'react': {
        commonjs: 'react',
        commonjs2: 'react',
        amd: 'React',
        root: 'React'
    }
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel'],
        include: config.paths.src
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'dist') {
  module.exports = merge(distCommon, {
    output: {
      filename: config.filename + '.js'
    }
  });
}

if (TARGET === 'dist-min') {
  module.exports = merge(distCommon, {
    output: {
      filename: config.filename + '.min.js'
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

function renderJSX(demoTemplate, templateParams, compilation) {
  demoTemplate = demoTemplate || '';

  var tpl = fs.readFileSync(path.join(__dirname, 'lib/index_template.tpl'), 'utf8');
  var readme = fs.readFileSync(path.join(__dirname, 'README.md'), 'utf8');
  var replacements = {
    name: pkg.name,
    description: pkg.description,
    demo: demoTemplate,
    documentation: ReactDOM.renderToStaticMarkup(

{MTRC(readme).tree}

    )
  };

  return tpl.replace(/%(\w*)%/g, function(match) {
    var key = match.slice(1, -1);

    return replacements[key] ? replacements[key] : match;
  });
}
<commit_msg>Add missing `chunkFilename`<commit_after>'use strict';
import fs from 'fs';
import path from 'path';

import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import SystemBellPlugin from 'system-bell-webpack-plugin';
import Clean from 'clean-webpack-plugin';
import merge from 'webpack-merge';
import React from 'react';
import ReactDOM from 'react-dom/server';
import MTRC from 'markdown-to-react-components';

import App from './demo/App.jsx';
import pkg from './package.json';

const TARGET = process.env.npm_lifecycle_event;
const ROOT_PATH = __dirname;
const config = {
  paths: {
    dist: path.join(ROOT_PATH, 'dist'),
    src: path.join(ROOT_PATH, 'src'),
    demo: path.join(ROOT_PATH, 'demo'),
    tests: path.join(ROOT_PATH, 'tests')
  },
  filename: 'boilerplate',
  library: 'Boilerplate'
};
const CSS_PATHS = [
  config.paths.demo,
  path.join(ROOT_PATH, 'style.css'),
  path.join(ROOT_PATH, 'node_modules/purecss'),
  path.join(ROOT_PATH, 'node_modules/highlight.js/styles/github.css'),
  path.join(ROOT_PATH, 'node_modules/react-ghfork/gh-fork-ribbon.ie.css'),
  path.join(ROOT_PATH, 'node_modules/react-ghfork/gh-fork-ribbon.css')
];

process.env.BABEL_ENV = TARGET;

const demoCommon = {
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.png', '.jpg']
  },
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        include: [
          config.paths.demo,
          config.paths.src
        ]
      }
    ],
    loaders: [
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
        include: config.paths.demo
      },
      {
        test: /\.jpg$/,
        loader: 'file',
        include: config.paths.demo
      },
      {
        test: /\.json$/,
        loader: 'json',
        include: path.join(ROOT_PATH, 'package.json')
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'start') {
  module.exports = merge(demoCommon, {
    devtool: 'eval-source-map',
    entry: config.paths.demo,
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('development')
      }),
      new HtmlWebpackPlugin({
        title: pkg.name + ' - ' + pkg.description,
        templateContent: renderJSX
      }),
      new webpack.HotModuleReplacementPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loaders: ['style', 'css'],
          include: CSS_PATHS
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.demo,
            config.paths.src
          ]
        }
      ]
    },
    devServer: {
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,
      host: process.env.HOST,
      port: process.env.PORT,
      stats: 'errors-only'
    }
  });
}

if (TARGET === 'gh-pages' || TARGET === 'deploy-gh-pages') {
  module.exports = merge(demoCommon, {
    entry: {
      app: config.paths.demo,
      vendors: [
        'react'
      ]
    },
    output: {
      path: './gh-pages',
      filename: 'bundle.[chunkhash].js',
      chunkFilename: '[chunkhash].js'
    },
    plugins: [
      new Clean(['gh-pages']),
      new ExtractTextPlugin('styles.[chunkhash].css'),
      new webpack.DefinePlugin({
          // This has effect on the react lib size
        'process.env.NODE_ENV': JSON.stringify('production')
      }),
      new HtmlWebpackPlugin({
        title: pkg.name + ' - ' + pkg.description,
        templateContent: renderJSX.bind(null, ReactDOM.renderToString(<App />))
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      }),
      new webpack.optimize.CommonsChunkPlugin({
        names: ['vendors', 'manifest']
      }),
      new webpack.NamedModulesPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css'),
          include: CSS_PATHS
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.demo,
            config.paths.src
          ]
        }
      ]
    }
  });
}

// !TARGET === prepush hook for test
if (TARGET === 'test' || TARGET === 'tdd' || !TARGET) {
  module.exports = merge(demoCommon, {
    module: {
      preLoaders: [
        {
          test: /\.jsx?$/,
          loaders: ['eslint'],
          include: [
            config.paths.tests
          ]
        }
      ],
      loaders: [
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.src,
            config.paths.tests
          ]
        }
      ]
    }
  })
}

const distCommon = {
  devtool: 'source-map',
  output: {
    path: config.paths.dist,
    libraryTarget: 'umd',
    library: config.library
  },
  entry: config.paths.src,
  externals: {
    'react': {
        commonjs: 'react',
        commonjs2: 'react',
        amd: 'React',
        root: 'React'
    }
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel'],
        include: config.paths.src
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'dist') {
  module.exports = merge(distCommon, {
    output: {
      filename: config.filename + '.js'
    }
  });
}

if (TARGET === 'dist-min') {
  module.exports = merge(distCommon, {
    output: {
      filename: config.filename + '.min.js'
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

function renderJSX(demoTemplate, templateParams, compilation) {
  demoTemplate = demoTemplate || '';

  var tpl = fs.readFileSync(path.join(__dirname, 'lib/index_template.tpl'), 'utf8');
  var readme = fs.readFileSync(path.join(__dirname, 'README.md'), 'utf8');
  var replacements = {
    name: pkg.name,
    description: pkg.description,
    demo: demoTemplate,
    documentation: ReactDOM.renderToStaticMarkup(

{MTRC(readme).tree}

    )
  };

  return tpl.replace(/%(\w*)%/g, function(match) {
    var key = match.slice(1, -1);

    return replacements[key] ? replacements[key] : match;
  });
}
<|endoftext|>


<commit_before>'use strict';

describe('ステージ5（意図通りに非同期処理を利用できる）', function() {
  describe('Promise 編', function() {
    it('resolve ハンドラーを書ける', function(testDone){
      var promise = Promise.resolve('resolved!');

      // チュートリアル
      //
      // ここに下記のコードを記述してください。
      //
      // promise.then(function(msg) {
      //   expect(msg).to.equal('resolved!');
      //   testDone();
      // });
    });

    it('reject ハンドラーを書ける', function(testDone){
      var promise = Promise.reject('rejected!');

      // reject ハンドラーを使って、下の assertion が promise の
      // エラー値を検証できるように記述してください。
      //
      // expect(msg).to.equal('rejected!');
      // testDone();

      // ここにコードを記述してください。

    });

    it('複数の promise すべての完了を待つ promise を作成できる', function() {
      var messageFragments = ['あなたと', 'java', '今すぐダウンロード'];
      var promise1 = createWaitPromise(messageFragments[0], 10);
      var promise2 = createWaitPromise(messageFragments[1], 20);
      var promise3 = createWaitPromise(messageFragments[2], 30);

      // 作成した promise を promise 変数に代入してください。
      var promise = 'change me!';

      return expect(promise).to.eventually.deep.equal(messageFragments);
    });

    it('複数の promise のうち最も速く解決された値をもつ promise を作成できる', function() {
      var messageFragments = ['30億の', 'デバイスで', '走るjava'];
      var promise1 = createWaitPromise(messageFragments[0], 30);
      var promise2 = createWaitPromise(messageFragments[1], 10);
      var promise3 = createWaitPromise(messageFragments[2], 30);

      // 作成した promise を promise 変数に代入してください。
      var promise = 'change me!';

      return expect(promise).to.eventually.equal(messageFragments[1]);
    });
  });

  describe('fetch API 編', function() {
    it('/api/friends API を使って Sugar の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Sugar';

      // チュートリアル
      //
      // ここに下記のコードを記述してください。
      //
      // var promisedFriends = fetch(api + username).then(function(res) {
      //   return res.json();
      // });

      return expect(promisedFriends).to.eventually.deep.equal(['PYXC-PJ']);
    });

    it('/api/friends API を使って Shen の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Shen';

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(
        ['jisp', 'TeJaS']
      );
    });

    it('/api/friends API を使って Shen の友人の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Shen';

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(['TypeScript']);
    });

    it.skip('/api/friends API を使って CoffeeScript の友人を再帰的に取得できる', function() {
      // 難易度高いので、自信のある人だけ挑戦してください。
      // it.skip の .skip を消せば、テストが走るようになります。

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(
        ['Taijilang', 'purescript', 'Wind.js', 'ScriptBlocks', 'jangaroo']
      );
    });

    it('Github の mixi-inc の organization の情報を取得できる', function() {

      // 作成した promise を mixiOrg 変数に代入してください。
      var mixiOrg = 'change me!';

      return expect(mixiOrg).to.eventually.have.property('id', 1089312);

      // Github API に関する参考情報
      // https://developer.github.com/v3/repos/
    });

    it('Github API を使って、mixi-inc/JavaScriptTraining の情報を取得できる', function() {
      var repositry = 'mixi-inc/JavaScriptTraining';

      // 作成した promise を mixiRepo 変数に代入してください。
      var mixiRepo = 'change me!';

      return expect(mixiRepo).to.eventually.have.property('full_name', repositry);

      // Github API に関する参考情報
      // https://developer.github.com/v3/orgs
    });

    it('Github API を使って、VimL、Emacs Lisp でスターが最も多いプロダクト名を' +
       'それぞれ 1 つずつ取得できる', function() {
      var languages = [ 'VimL', '"Emacs Lisp"' ];
      var mostPopularRepos = 'change me!';

      // 作成した promise を mostPopularRepos 変数に代入してください。

      return expect(mostPopularRepos).to.eventually.have.length(2);

      // Github API に関する参考情報
      // https://developer.github.com/v3/search
    });
  });

  function createWaitPromise(value, msec) {
    return new Promise(function(resolve) {
      setTimeout(resolve, msec, value);
    });
  }
});
<commit_msg>fix typos<commit_after>'use strict';

describe('ステージ5（意図通りに非同期処理を利用できる）', function() {
  describe('Promise 編', function() {
    it('resolve ハンドラーを書ける', function(testDone){
      var promise = Promise.resolve('resolved!');

      // チュートリアル
      //
      // ここに下記のコードを記述してください。
      //
      // promise.then(function(msg) {
      //   expect(msg).to.equal('resolved!');
      //   testDone();
      // });
    });

    it('reject ハンドラーを書ける', function(testDone){
      var promise = Promise.reject('rejected!');

      // reject ハンドラーを使って、下の assertion が promise の
      // エラー値を検証できるように記述してください。
      //
      // expect(msg).to.equal('rejected!');
      // testDone();

      // ここにコードを記述してください。

    });

    it('複数の promise すべての完了を待つ promise を作成できる', function() {
      var messageFragments = ['あなたと', 'java', '今すぐダウンロード'];
      var promise1 = createWaitPromise(messageFragments[0], 10);
      var promise2 = createWaitPromise(messageFragments[1], 20);
      var promise3 = createWaitPromise(messageFragments[2], 30);

      // 作成した promise を promise 変数に代入してください。
      var promise = 'change me!';

      return expect(promise).to.eventually.deep.equal(messageFragments);
    });

    it('複数の promise のうち最も速く解決された値をもつ promise を作成できる', function() {
      var messageFragments = ['30億の', 'デバイスで', '走るjava'];
      var promise1 = createWaitPromise(messageFragments[0], 30);
      var promise2 = createWaitPromise(messageFragments[1], 10);
      var promise3 = createWaitPromise(messageFragments[2], 30);

      // 作成した promise を promise 変数に代入してください。
      var promise = 'change me!';

      return expect(promise).to.eventually.equal(messageFragments[1]);
    });
  });

  describe('fetch API 編', function() {
    it('/api/friends API を使って Sugar の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Sugar';

      // チュートリアル
      //
      // ここに下記のコードを記述してください。
      //
      // var promisedFriends = fetch(api + username).then(function(res) {
      //   return res.json();
      // });

      return expect(promisedFriends).to.eventually.deep.equal(['PYXC-PJ']);
    });

    it('/api/friends API を使って Shen の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Shen';

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(
        ['jisp', 'TeJaS']
      );
    });

    it('/api/friends API を使って Shen の友人の友人を取得できる', function() {
      var api = '/api/friends/';
      var username = 'Shen';

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(['TypeScript']);
    });

    it.skip('/api/friends API を使って CoffeeScript の友人を再帰的に取得できる', function() {
      // 難易度高いので、自信のある人だけ挑戦してください。
      // it.skip の .skip を消せば、テストが走るようになります。

      // 作成した promise を promisedFriends 変数に代入してください。
      var promisedFriends = 'change me!';

      return expect(promisedFriends).to.eventually.deep.equal(
        ['Taijilang', 'purescript', 'Wind.js', 'ScriptBlocks', 'jangaroo']
      );
    });

    it('Github の mixi-inc の organization の情報を取得できる', function() {

      // 作成した promise を mixiOrg 変数に代入してください。
      var mixiOrg = 'change me!';

      return expect(mixiOrg).to.eventually.have.property('id', 1089312);

      // Github API に関する参考情報
      // https://developer.github.com/v3/orgs
    });

    it('Github API を使って、mixi-inc/JavaScriptTraining の情報を取得できる', function() {
      var repository = 'mixi-inc/JavaScriptTraining';

      // 作成した promise を mixiRepo 変数に代入してください。
      var mixiRepo = 'change me!';

      return expect(mixiRepo).to.eventually.have.property('full_name', repository);

      // Github API に関する参考情報
      // https://developer.github.com/v3/repos/
    });

    it('Github API を使って、VimL、Emacs Lisp でスターが最も多いプロダクト名を' +
       'それぞれ 1 つずつ取得できる', function() {
      var languages = [ 'VimL', '"Emacs Lisp"' ];
      var mostPopularRepos = 'change me!';

      // 作成した promise を mostPopularRepos 変数に代入してください。

      return expect(mostPopularRepos).to.eventually.have.length(2);

      // Github API に関する参考情報
      // https://developer.github.com/v3/search
    });
  });

  function createWaitPromise(value, msec) {
    return new Promise(function(resolve) {
      setTimeout(resolve, msec, value);
    });
  }
});
<|endoftext|>


<commit_before>import path from "path";
import webpack from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ExtractTextPlugin from "extract-text-webpack-plugin";
import CopyWebpackPlugin from "copy-webpack-plugin";
import autoprefixer from "autoprefixer";

const isProduction = process.env.NODE_ENV === "production";

export default {
  context: path.resolve(__dirname, "src"),
  devtool: isProduction ? "source-map" : false,
  entry: {
    polyfills: ["./setup"],
    panel: ["./setupPanel"],
    injector: ["./prompt-injector"],
    background: ["./background"],
    prompt: ["./prompt"],
    record: ["./record"],
    escape: ["./escape"],
    neo: ["react-hot-loader/patch", "./neo/containers/Root"]
  },
  output: {
    path: path.resolve(__dirname, "build/assets"),
    filename: "[name].js",
    publicPath: "/assets/",
    libraryTarget: "umd"
  },
  resolve: {
    extensions: [".js", ".jsx", ".json"]
  },
  module: {
    rules: [
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works just like "file" loader but it also embeds
          // assets smaller than specified size as data URLs to avoid requests.
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: "url-loader",
            options: {
              limit: 10000,
              name: "media/[name].[hash:8].[ext]"
            }
          },
          // Process JS with Babel.
          {
            test: /\.(jsx?)$/,
            include: [
              path.resolve(__dirname, "src")
            ],
            loader: "babel-loader",
            options: {
              compact: true
            }
          },
          // The notation here is somewhat confusing.
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader normally turns CSS into JS modules injecting <style>,
          // but unlike in development configuration, we do something different.
          // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
          // (second argument), then grabs the result CSS and puts it into a
          // separate file in our build process. This way we actually ship
          // a single CSS file in production instead of JS code injecting <style>
          // tags. If you use code splitting, however, any async bundles will still
          // use the "style" loader inside the async code so CSS from them won't be
          // in the main CSS file.
          {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract(
              {
                fallback: "style-loader",
                use: [
                  {
                    loader: "css-loader",
                    options: {
                      importLoaders: 1,
                      minimize: true,
                      sourceMap: isProduction
                    }
                  },
                  {
                    loader: "postcss-loader",
                    options: {
                      // Necessary for external CSS imports to work
                      // https://github.com/facebookincubator/create-react-app/issues/2677
                      ident: "postcss",
                      plugins: () => [
                        require("postcss-flexbugs-fixes"),
                        autoprefixer({
                          browsers: [
                            ">1%",
                            "last 4 versions",
                            "Firefox ESR",
                            "not ie < 9" // React doesn't support IE8 anyway
                          ],
                          flexbox: "no-2009"
                        })
                      ]
                    }
                  }
                ]
              }
            )
            // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
          },
          // "file" loader makes sure assets end up in the `build` folder.
          // When you `import` an asset, you get its filename.
          // This loader don't uses a "test" so it will catch all modules
          // that fall through the other loaders.
          {
            loader: "file-loader",
            // Exclude `js` files to keep "css" loader working as it injects
            // it's runtime that would otherwise processed through "file" loader.
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
            exclude: [/\.jsx?$/, /\.html$/, /\.json$/],
            options: {
              name: "media/[name].[hash:8].[ext]"
            }
          }
          // ** STOP ** Are you adding a new loader?
          // Make sure to add the new loader(s) before the "file" loader.
        ]
      }
    ]
  },
  plugins: [
    // Copy non-umd assets to vendor
    new CopyWebpackPlugin([
      { from: "", to: "vendor" }
    ]),
    // Generates an `index.html` file with the <script> injected.
    new HtmlWebpackPlugin({
      filename: "index.html",
      inject: true,
      template: path.resolve(__dirname, "src/neo/index.html"),
      chunks: ["neo"],
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      }
    }),
    // Generates an `index.html` file with the <script> injected.
    new HtmlWebpackPlugin({
      filename: "panel.html",
      inject: "head",
      template: path.resolve(__dirname, "src/panel.html"),
      chunks: [],
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      }
    }),
    // Makes some environment variables available to the JS code, for example:
    // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
    // It is absolutely essential that NODE_ENV was set to production here.
    // Otherwise React will be compiled in the very slow development mode.
    new webpack.DefinePlugin({
      "process.env": {
        "NODE_ENV": JSON.stringify(process.env.NODE_ENV)
      }
    }),
    // Minify the code.
    /*new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        // Disabled because of an issue with Uglify breaking seemingly valid code:
        // https://github.com/facebookincubator/create-react-app/issues/2376
        // Pending further investigation:
        // https://github.com/mishoo/UglifyJS2/issues/2011
        comparisons: false
      },
      output: {
        comments: false,
        // Turned on because emoji and regex is not minified properly using default
        // https://github.com/facebookincubator/create-react-app/issues/2488
        ascii_only: true
      },
      sourceMap: isProduction
    }),*/
    // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
    new ExtractTextPlugin({
      filename: "css/[name].[hash:8].css"
    }),
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};
<commit_msg>development plugins<commit_after>import path from "path";
import webpack from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ExtractTextPlugin from "extract-text-webpack-plugin";
import CopyWebpackPlugin from "copy-webpack-plugin";
import autoprefixer from "autoprefixer";

const isProduction = process.env.NODE_ENV === "production";

export default {
  context: path.resolve(__dirname, "src"),
  devtool: isProduction ? "source-map" : false,
  entry: {
    polyfills: ["./setup"],
    panel: ["./setupPanel"],
    injector: ["./prompt-injector"],
    background: ["./background"],
    prompt: ["./prompt"],
    record: ["./record"],
    escape: ["./escape"],
    neo: ["react-hot-loader/patch", "./neo/containers/Root"]
  },
  output: {
    path: path.resolve(__dirname, "build/assets"),
    filename: "[name].js",
    publicPath: "/assets/",
    libraryTarget: "umd"
  },
  resolve: {
    extensions: [".js", ".jsx", ".json"]
  },
  module: {
    rules: [
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
          // "url" loader works just like "file" loader but it also embeds
          // assets smaller than specified size as data URLs to avoid requests.
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            loader: "url-loader",
            options: {
              limit: 10000,
              name: "media/[name].[hash:8].[ext]"
            }
          },
          // Process JS with Babel.
          {
            test: /\.(jsx?)$/,
            include: [
              path.resolve(__dirname, "src")
            ],
            loader: "babel-loader",
            options: {
              compact: true
            }
          },
          // The notation here is somewhat confusing.
          // "postcss" loader applies autoprefixer to our CSS.
          // "css" loader resolves paths in CSS and adds assets as dependencies.
          // "style" loader normally turns CSS into JS modules injecting <style>,
          // but unlike in development configuration, we do something different.
          // `ExtractTextPlugin` first applies the "postcss" and "css" loaders
          // (second argument), then grabs the result CSS and puts it into a
          // separate file in our build process. This way we actually ship
          // a single CSS file in production instead of JS code injecting <style>
          // tags. If you use code splitting, however, any async bundles will still
          // use the "style" loader inside the async code so CSS from them won't be
          // in the main CSS file.
          {
            test: /\.css$/,
            loader: isProduction ? ExtractTextPlugin.extract(
              {
                fallback: "style-loader",
                use: [
                  {
                    loader: "css-loader",
                    options: {
                      importLoaders: 1,
                      minimize: true,
                      sourceMap: isProduction
                    }
                  },
                  {
                    loader: "postcss-loader",
                    options: {
                      // Necessary for external CSS imports to work
                      // https://github.com/facebookincubator/create-react-app/issues/2677
                      ident: "postcss",
                      plugins: () => [
                        require("postcss-flexbugs-fixes"),
                        autoprefixer({
                          browsers: [
                            ">1%",
                            "last 4 versions",
                            "Firefox ESR",
                            "not ie < 9" // React doesn't support IE8 anyway
                          ],
                          flexbox: "no-2009"
                        })
                      ]
                    }
                  }
                ]
              }
            ) : [
              require.resolve("style-loader"),
              {
                loader: require.resolve("css-loader"),
                options: {
                  importLoaders: 1
                }
              },
              {
                loader: require.resolve("postcss-loader"),
                options: {
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: "postcss",
                  plugins: () => [
                    require("postcss-flexbugs-fixes"),
                    autoprefixer({
                      browsers: [
                        ">1%",
                        "last 4 versions",
                        "Firefox ESR",
                        "not ie < 9" // React doesn't support IE8 anyway
                      ],
                      flexbox: "no-2009"
                    })
                  ]
                }
              }
            ]
            // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
          },
          // "file" loader makes sure assets end up in the `build` folder.
          // When you `import` an asset, you get its filename.
          // This loader don't uses a "test" so it will catch all modules
          // that fall through the other loaders.
          {
            loader: "file-loader",
            // Exclude `js` files to keep "css" loader working as it injects
            // it's runtime that would otherwise processed through "file" loader.
            // Also exclude `html` and `json` extensions so they get processed
            // by webpacks internal loaders.
            exclude: [/\.jsx?$/, /\.html$/, /\.json$/],
            options: {
              name: "media/[name].[hash:8].[ext]"
            }
          }
          // ** STOP ** Are you adding a new loader?
          // Make sure to add the new loader(s) before the "file" loader.
        ]
      }
    ]
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    // Copy non-umd assets to vendor
    new CopyWebpackPlugin([
      { from: "", to: "vendor" }
    ]),
    // Generates an `index.html` file with the <script> injected.
    new HtmlWebpackPlugin({
      filename: "index.html",
      inject: true,
      template: path.resolve(__dirname, "src/neo/index.html"),
      chunks: ["neo"],
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      }
    }),
    // Generates an `index.html` file with the <script> injected.
    new HtmlWebpackPlugin({
      filename: "panel.html",
      inject: "head",
      template: path.resolve(__dirname, "src/panel.html"),
      chunks: [],
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      }
    }),
    // Makes some environment variables available to the JS code, for example:
    // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
    // It is absolutely essential that NODE_ENV was set to production here.
    // Otherwise React will be compiled in the very slow development mode.
    new webpack.DefinePlugin({
      "process.env": {
        "NODE_ENV": JSON.stringify(process.env.NODE_ENV)
      }
    }),
    // Minify the code.
    /*new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        // Disabled because of an issue with Uglify breaking seemingly valid code:
        // https://github.com/facebookincubator/create-react-app/issues/2376
        // Pending further investigation:
        // https://github.com/mishoo/UglifyJS2/issues/2011
        comparisons: false
      },
      output: {
        comments: false,
        // Turned on because emoji and regex is not minified properly using default
        // https://github.com/facebookincubator/create-react-app/issues/2488
        ascii_only: true
      },
      sourceMap: isProduction
    }),*/
    // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
    new ExtractTextPlugin({
      filename: "css/[name].[hash:8].css"
    }),
    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};
<|endoftext|>


<commit_before>import {join} from 'path';
import webpack from 'webpack';

process.env.BABEL_ENV = 'browser';

function config({production}) {
    return {
        devtool: production ? 'hidden-source-map' : 'eval-source-map',
        entry: './src/index.js',
        output: {
            path: join(__dirname, 'dist'),
            library: 'WHS',
            libraryTarget: 'umd'
        },
        module: {
            loaders: [
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel'
                }
            ]
        },
        plugins: production ?
            [
                new webpack.optimize.DedupePlugin(),
                new webpack.optimize.UglifyJsPlugin({
                    mangle: false,
                    compress: {
                        warnings: false
                    }
                })
            ] :
            []
    };
}

export {
    config as default
};
<commit_msg>Fix webpack.<commit_after>import {join} from 'path';
import webpack from 'webpack';

process.env.BABEL_ENV = 'browser';

function config({production}) {
  return {
    devtool: production ? 'hidden-source-map' : 'eval-source-map',
    entry: './src/index.js',
    output: {
      path: join(__dirname, 'build'),
      filename: 'whitestorm.js',
      library: 'WHS',
      libraryTarget: 'umd'
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel'
        }
      ]
    },
    plugins: production
      ? [
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.UglifyJsPlugin({
          mangle: false,
          compress: {
            warnings: false
          }
        })
      ]
      : []
  };
}

export {
  config as default
};
<|endoftext|>


<commit_before>/* eslint-disable no-console */
import express from 'express';
import webpack from 'webpack';
import bodyParser from 'body-parser'
import path from 'path';
import config from '../../webpack.config.js';

import socket from 'socket.io';

const PORT = 8080;
const app = express();
const compiler = webpack(config);

let room;

app.use(bodyParser.urlencoded({ extended: false }))

app.use(
  require('webpack-dev-middleware')(compiler, {
    noInfo: true,
    publicPath: config.output.staticsPath,
  }),
);

app.use(require('webpack-hot-middleware')(compiler, {
  noInfo: true,
  staticsPath: config.output.staticsPath
}));

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '../../static/index.html'));
});

const server = app.listen(PORT, '127.0.0.1', (err) => {
  if (err) {
    console.log(err);
  } else {
    console.log(`http://localhost:${PORT}`);
  }
});

const io = socket(server);

app.post('/', (req, res) => {
  const { Body, From } = req.body
  const message = {
    body: Body,
    from: From.slice(8)
  }
  io.emit('message', message)
})

io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('subscribe', data => {
    room = data.room;
    socket.join(room);
    console.log('joined room', room);
  });
  socket.on('unsubscribe', () => {
    socket.leave(room);
    console.log('leaving room', room);
  });
  socket.on('disconnect', () => {
    console.log('a user disconnected');
  });

  socket.on('chat message', (msg) => {
    console.log('sending message to', msg.room);
    console.log('this message', msg);
    io.to(msg.room).emit('chat message', JSON.stringify(msg));
  });
});
<commit_msg>messages working between client and server instances<commit_after>/* eslint-disable no-console */
import express from 'express';
import webpack from 'webpack';
import bodyParser from 'body-parser'
import path from 'path';
import config from '../../webpack.config.js';

import socket from 'socket.io';

const PORT = 8080;
const app = express();
const compiler = webpack(config);

let room;

app.use(bodyParser.urlencoded({ extended: false }))

app.use(
  require('webpack-dev-middleware')(compiler, {
    noInfo: true,
    publicPath: config.output.staticsPath,
  }),
);

app.use(require('webpack-hot-middleware')(compiler, {
  noInfo: true,
  staticsPath: config.output.staticsPath
}));

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '../../static/index.html'));
});

const server = app.listen(PORT, '127.0.0.1', (err) => {
  if (err) {
    console.log(err);
  } else {
    console.log(`http://localhost:${PORT}`);
  }
});

const io = socket(server);

app.post('/', (req, res) => {
  console.log('hitting / post route in server');
  const { Body, From } = req.body
  const message = {
    body: Body,
    from: From.slice(8)
  }
  io.emit('message', message)
})

io.on('connection', socket => {
  socket.on('message', body => {
    socket.broadcast.emit('message', {
      body,
      from: socket.id.slice(8)
    })
  })
})

// io.on('connection', (socket) => {
//   console.log('a user connected');
//   socket.on('subscribe', data => {
//     room = data.room;
//     socket.join(room);
//     console.log('joined room', room);
//   });
//   socket.on('unsubscribe', () => {
//     socket.leave(room);
//     console.log('leaving room', room);
//   });
//   socket.on('disconnect', () => {
//     console.log('a user disconnected');
//   });

//   socket.on('chat message', (msg) => {
//     console.log('sending message to', msg.room);
//     console.log('this message', msg);
//     io.to(msg.room).emit('chat message', JSON.stringify(msg));
//   });
// });
<|endoftext|>


<commit_before>! function(window, angular, undefined) {
  angular.module('ds.map', []).
  factory('dsMapFactory', ['$http', function($http) {
    var defaultMapSettings = {
        center: {
          lat: 12.94206,
          lng: 77.62229
        },
        zoom: 8
      },
      obj = {
        getDefaultMapSettings: function() {
          return defaultMapSettings;
        },
        setDefaultMapSettings: function(settingsObj) {
          defaultMapSettings = settingsObj;
        }
      };
    return obj;
  }]).
  directive('dsMap', ['$q', '$timeout', 'dsMapFactory', function($q, $timeout, dsMapFactory) {
    var deferred = $q.defer(),
      obj = {
        scope: {
          dsMapSettings: "="
        },
        restrict: "E",
        link: function(scope) {

        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          var _deferred = $q.defer(),
            dsMapElements = 0,
            deferredArray = [],
            that = this,
            dsMapSettings = that.dsMapSettings = $scope.dsMapSettings || dsMapFactory.getDefaultMapSettings(),
            map = new google.maps.Map(document.createElement('div'), dsMapSettings);

          this.mapDeferred = deferred;
          this.mapRendered = deferred.promise;

          this.getLocation = function() {
            return that.dsPlacesLocation;
          };

          this.setLocation = function(center) {
            that.dsPlacesLocation = center || that.getMap().getCenter();
          };

          this.getMap = function() {
            return that.map;
          };

          this.setMap = function(map) {
            dsMapFactory.map = that.map = map;
            this.setLocation(that.map.getCenter());
            dsMapFactory.marker = {
              position: that.map.getCenter(),
              map: that.map
            };
          };

          that.setMap(map);

          (function(dfrd, _dfrd) {
            that.mapRendered.then(function() {
              var marker = new google.maps.Marker(dsMapFactory.marker);
              marker.setMap(that.getMap());

              $timeout(function() {
                _dfrd.resolve();
              }, 5000);
            });
          })(deferred, _deferred);

          deferred = _deferred;
        }]
      };
    return obj;
  }]).
  directive('dsMapView', function() {
    var obj = {
      scope: {
        dsMapSettings: "="
      },
      restrict: "E",
      replace: true,
      template: "

",
      require: "^?dsMap",
      link: function(scope, element, attrs, dsMapController) {
        var map = new google.maps.Map(element[0], scope.dsMapSettings || dsMapController.dsMapSettings);
        dsMapController.setMap(map);
        dsMapController.isViewSet = true;
      },
      controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {

      }]
    };
    return obj;
  }).directive('dsMapPlaces', ['$q', function($q) {
    var initialdsMapView = true,
      deferred = $q.defer(),
      obj = {
        scope: {

        },
        restrict: "E",
        replace: true,
        require: "^?dsMap",
        link: function(scope, element, attrs, dsMapController) {
          var rankByDistance = google.maps.places.RankBy.DISTANCE;
          if (initialdsMapView) {
            dsMapController.mapDeferred.resolve();
            initialdsMapView = false;
          }

          dsMapController.mapRendered.then(function() {
            dsMapController.placesService = new google.maps.places.PlacesService(dsMapController.getMap());
            dsMapController.directionsService = new google.maps.DirectionsService();
            dsMapController.directionsDisplay = new google.maps.DirectionsRenderer({
              map: dsMapController.getMap(),
              preserveViewport: true
            });
            dsMapController.bounds = new google.maps.LatLngBounds();
            deferred.resolve(dsMapController.placesService);
          });
        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          this.placesServiceSet = deferred.promise;
        }]
      };
    return obj;
  }]).directive('dsPlacesType', ['$q', '$timeout', function($q, $timeout) {
    var deferred = $q.defer(),
      placesServiceCount = 0,
      obj = {
        scope: {
          types: "=",
          sortOption: "@",
          radius: "="
        },
        templateUrl: "dsMapPlaces.html",
        restrict: "E",
        replace: true,
        require: ["^?dsMap", "^?dsMapPlaces"],
        link: function(scope, element, attrs, dsMapControllers) {
          var dsMapController = dsMapControllers[0],
            dsMapPlacesController = dsMapControllers[1],
            obj = {
              location: dsMapController.getMap().getCenter(),
              types: []
            };

          function callPlacesService(dfrd, _dfrd, type) {
            dsMapController.mapRendered.then(function() {
              dfrd.promise.then(function() {
                dsMapPlacesController.placesServiceSet.then(function(placesService) {
                  if (type) {
                    obj.types = [type];
                  }
                  placesService.nearbySearch(obj, function(results, status) {
                    if (Object.prototype.toString.call(results) == "[object Array]") {
                      scope.Places = scope.Places.concat(type === undefined ? results : results.slice(0, scope.types[type]));
                    }
                    $timeout(function() {
                      _dfrd.resolve();
                    }, 300);
                  });
                });
              });
            });
          }

          if (scope.sortOption && scope.sortOption == "radius") {
            obj.radius = scope.radius || 5000;
          } else {
            obj.rankBy = google.maps.places.RankBy.DISTANCE;
          }

          if (Object.prototype.toString.call(scope.types) == "[object Array]") {
            var _deferred = $q.defer();
            obj.types = scope.types;
            callPlacesService(deferred, _deferred);
            deferred = _deferred;
          } else if (Object.prototype.toString.call(scope.types) == "[object Object]") {
            for (var _types in scope.types) {
              (function(_deferred) {
                _deferred = $q.defer();
                callPlacesService(deferred, _deferred, _types);
                deferred = _deferred;
              })(_deferred);
            }
          } else {
            throw "'types' attribute must be an array or object"
          }

          if (dsMapController.isViewSet) {
            scope.showDirection = function() {
              var request = {
                  origin: dsMapController.getLocation(),
                  destination: this.place.geometry.location,
                  travelMode: google.maps.TravelMode["DRIVING"]
                },
                that = this;

              try {
                if (that.isDirectionResponseCallMade) {
                  if (that.directionResponse) {
                    dsMapController.directionsDisplay.setDirections(that.directionResponse);
                  }
                  return;
                }
                that.isDirectionResponseCallMade = true;
                dsMapController.directionsService.route(request, function(response, status) {
                  dsMapController.directionsDisplay.setDirections(that.directionResponse = response);
                });
              } catch (err) {}
            };
          }
        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          $scope.Places = [];
        }]
      };

    deferred.resolve();

    return obj;
  }]).directive('dsWithinBounds', [function() {
    var obj = {
      require: ["^?dsMap", "^?dsMapPlaces", "^?dsPlacesType"],
      link: function(scope, element, attrs, dsMapControllers) {
        var dsMapController = dsMapControllers[0],
          dsMapPlacesController = dsMapControllers[1],
          dsPlacesTypeController = dsMapControllers[2];

        if (scope.place) {
          dsMapController.bounds.extend(scope.place.geometry.location);
          dsMapController.getMap().fitBounds(dsMapController.bounds);
          dsMapController.getMap().setCenter(dsMapController.getLocation());
        }
      }
    };

    return obj;
  }]);
}(window, window.angular);
<commit_msg>Execute non-concurrent calls more any number of dsMap elements<commit_after>! function(window, angular, undefined) {
  angular.module('ds.map', []).
  factory('dsMapFactory', ['$http', function($http) {
    var defaultMapSettings = {
        center: {
          lat: 12.94206,
          lng: 77.62229
        },
        zoom: 8
      },
      obj = {
        getDefaultMapSettings: function() {
          return defaultMapSettings;
        },
        setDefaultMapSettings: function(settingsObj) {
          defaultMapSettings = settingsObj;
        }
      };
    return obj;
  }]).
  directive('dsMap', ['$q', '$timeout', 'dsMapFactory', function($q, $timeout, dsMapFactory) {
    var deferred = $q.defer(),
      obj = {
        scope: {
          dsMapSettings: "="
        },
        restrict: "E",
        link: function(scope) {

        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          var _deferred = $q.defer(),
            dsMapElements = 0,
            deferredArray = [],
            that = this,
            dsMapSettings = that.dsMapSettings = $scope.dsMapSettings || dsMapFactory.getDefaultMapSettings(),
            map = new google.maps.Map(document.createElement('div'), dsMapSettings);

          that.mapDeferred = deferred;
          that.mapRendered = deferred.promise;

          that.placesCount = 0;

          that.getLocation = function() {
            return that.dsPlacesLocation;
          };

          that.setLocation = function(center) {
            that.dsPlacesLocation = center || that.getMap().getCenter();
          };

          that.getMap = function() {
            return that.map;
          };

          that.setMap = function(map) {
            dsMapFactory.map = that.map = map;
            that.setLocation(that.map.getCenter());
            dsMapFactory.marker = {
              position: that.map.getCenter(),
              map: that.map
            };
          };

          that.setMap(map);

          (function(dfrd, _dfrd) {
            that.mapRendered.then(function() {
              var marker = new google.maps.Marker(dsMapFactory.marker);
              marker.setMap(that.getMap());
            });
          })(deferred, _deferred);

          that.nextDefer = deferred = _deferred;
        }]
      };
    return obj;
  }]).
  directive('dsMapView', function() {
    var obj = {
      scope: {
        dsMapSettings: "="
      },
      restrict: "E",
      replace: true,
      template: "

",
      require: "^?dsMap",
      link: function(scope, element, attrs, dsMapController) {
        var map = new google.maps.Map(element[0], scope.dsMapSettings || dsMapController.dsMapSettings);
        dsMapController.setMap(map);
        dsMapController.isViewSet = true;
      },
      controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {

      }]
    };
    return obj;
  }).directive('dsMapPlaces', ['$q', function($q) {
    var initialdsMapView = true,
      deferred = $q.defer(),
      obj = {
        scope: {

        },
        restrict: "E",
        replace: true,
        require: "^?dsMap",
        link: function(scope, element, attrs, dsMapController) {
          var rankByDistance = google.maps.places.RankBy.DISTANCE;
          if (initialdsMapView) {
            dsMapController.mapDeferred.resolve();
            initialdsMapView = false;
          }

          dsMapController.mapRendered.then(function() {
            dsMapController.placesService = new google.maps.places.PlacesService(dsMapController.getMap());
            dsMapController.directionsService = new google.maps.DirectionsService();
            dsMapController.directionsDisplay = new google.maps.DirectionsRenderer({
              map: dsMapController.getMap(),
              preserveViewport: true
            });
            dsMapController.bounds = new google.maps.LatLngBounds();
            deferred.resolve(dsMapController.placesService);
          });
        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          this.placesServiceSet = deferred.promise;
        }]
      };
    return obj;
  }]).directive('dsPlacesType', ['$q', '$timeout', function($q, $timeout) {
    var deferred = $q.defer(),
      placesServiceCount = 0,
      obj = {
        scope: {
          types: "=",
          sortOption: "@",
          radius: "="
        },
        templateUrl: "dsMapPlaces.html",
        restrict: "E",
        replace: true,
        require: ["^?dsMap", "^?dsMapPlaces"],
        link: function(scope, element, attrs, dsMapControllers) {
          var dsMapController = dsMapControllers[0],
            dsMapPlacesController = dsMapControllers[1],
            obj = {
              location: dsMapController.getMap().getCenter(),
              types: []
            };

          function callPlacesService(dfrd, _dfrd, type) {
            dsMapController.placesCount++;
            dsMapController.mapRendered.then(function() {
              dfrd.promise.then(function() {
                dsMapPlacesController.placesServiceSet.then(function(placesService) {
                  if (type) {
                    obj.types = [type];
                  }
                  placesService.nearbySearch(obj, function(results, status) {
                    if (Object.prototype.toString.call(results) == "[object Array]") {
                      scope.Places = scope.Places.concat(type === undefined ? results : results.slice(0, scope.types[type]));
                    }
                    $timeout(function() {
                      if((--dsMapController.placesCount)===0){
                        dsMapController.nextDefer.resolve();
                        dsMapController.nextDefer.promise.then(function(){
                          _dfrd.resolve();
                        });
                      }else{
                        _dfrd.resolve();
                      }
                    }, 300);
                  });
                });
              });
            });
          }

          if (scope.sortOption && scope.sortOption == "radius") {
            obj.radius = scope.radius || 5000;
          } else {
            obj.rankBy = google.maps.places.RankBy.DISTANCE;
          }

          if (Object.prototype.toString.call(scope.types) == "[object Array]") {
            var _deferred = $q.defer();
            obj.types = scope.types;
            callPlacesService(deferred, _deferred);
            deferred = _deferred;
          } else if (Object.prototype.toString.call(scope.types) == "[object Object]") {
            for (var _types in scope.types) {
              (function(_deferred) {
                _deferred = $q.defer();
                callPlacesService(deferred, _deferred, _types);
                deferred = _deferred;
              })(_deferred);
            }
          } else {
            throw "'types' attribute must be an array or object"
          }

          if (dsMapController.isViewSet) {
            scope.showDirection = function() {
              var that = this,
                request = {
                  origin: dsMapController.getLocation(),
                  destination: that.place.geometry.location,
                  travelMode: google.maps.TravelMode["DRIVING"]
                };

              try {
                if (that.isDirectionResponseCallMade) {
                  if (that.directionResponse) {
                    dsMapController.directionsDisplay.setDirections(that.directionResponse);
                  }
                  return;
                }
                that.isDirectionResponseCallMade = true;
                dsMapController.directionsService.route(request, function(response, status) {
                  dsMapController.directionsDisplay.setDirections(that.directionResponse = response);
                });
              } catch (err) {}
            };
          }
        },
        controller: ['$scope', '$element', '$attrs', function($scope, $element, $attr) {
          $scope.Places = [];
        }]
      };

    deferred.resolve();

    return obj;
  }]).directive('dsWithinBounds', [function() {
    var obj = {
      require: ["^?dsMap", "^?dsMapPlaces", "^?dsPlacesType"],
      link: function(scope, element, attrs, dsMapControllers) {
        var dsMapController = dsMapControllers[0],
          dsMapPlacesController = dsMapControllers[1],
          dsPlacesTypeController = dsMapControllers[2];

        if (scope.place) {
          dsMapController.bounds.extend(scope.place.geometry.location);
          dsMapController.getMap().fitBounds(dsMapController.bounds);
          dsMapController.getMap().setCenter(dsMapController.getLocation());
        }
      }
    };

    return obj;
  }]);
}(window, window.angular);
<|endoftext|>


<commit_before>/*
  backgrid-paginator
  http://github.com/wyuenho/backgrid

  Copyright (c) 2012 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/

(function ($, _, Backbone, Backgrid) {

  var PaginatorItem = Backgrid.PaginatorItem = Backbone.View.extend({

    tagName: "li",

    events: {
      "click a": "loadPage"
    },

    initialize: function (options) {
      this.label = options.label;
      this.page = options.page;
      this.hasAnchor = typeof options.hasAnchor !== "undefined" ? options.hasAnchor : true;
    },

    render: function () {
      var $a = $("" + this.label + "", {
        href: "#",
        title: "Page " + this.label
      });
      this.$el.append($a);

      return this;
    },

    loadPage: function (e) {
      e.preventDefault();
      if (!this.$el.hasClass("active") && !this.$el.hasClass('disabled')) {
        this.collection.goTo(this.page);
      }
    }

  });

  var Paginator = Backgrid.Paginator = Backgrid.Footer.extend({

    className: "paginator",

    windowSize: 10,
    hasFastForward: true,

    initialize: function (options) {
      Backgrid.Footer.prototype.initialize.apply(this, arguments);
      options = options ? _.clone(options) : {};
      this.parent = options.parent;
      this.columns = options.columns;
      if (!(this.columns instanceof Backbone.Collection)) {
        this.columns = new Backgrid.Columns(this.columns);
      }
      this.collection.on("reset", this.refresh, this);
      this.windowSize = options.windowSize || this.windowSize;
      this.hasFastForward = options.hasFastForward || this.hasFastForward;
      this.items = [];
    },

    dispose: function () {
      Backbone.View.prototype.dispose.apply(this, arguments);
      if (this.parent && this.parent.off) this.parent.off(null, null, this);
      this.columns.off(null, null, this);
      var item = null;
      for (var i = 0; i < this.items.length; i++) {
        item = this.items[i];
        item.off(null, null, this);
        item.dispose();
      }
      return this;
    },

    refresh: function () {
      var $ul = this.$el.find("ul");

      for (var i = 0; i < this.items.length; i++) {
        this.items[i].remove();
      }
      this.items = [];

      var collection = this.collection;

      // 0-based here
      var lastPage = collection.totalPages;
      var windowStart = Math.floor((collection.currentPage - 1) / this.windowSize) * this.windowSize;
      var windowEnd = windowStart + this.windowSize;
      windowEnd = windowEnd <= lastPage ? windowEnd : lastPage;
      for (var i = windowStart; i < windowEnd; i++) {
        // render link if not at current page
        var item = new PaginatorItem({
          label: i + 1,
          page: i + 1,
          className: i + 1 === collection.currentPage ? "active" : undefined,
          collection: collection
        });
        this.items.push(item);
        $ul.append(item.render().$el);
      }

      this.renderFastForward();
    },

    renderFastForward: function () {
      if (this.hasFastForward) {

        var $ul = this.$el.find("ul");
        var collection = this.collection;

        var gotoFirst = new PaginatorItem({
          label: "<<",
          page: 1,
          className: collection.currentPage > collection.firstPage ? undefined : "disabled",
          collection: collection
        });

        var gotoPrev = new PaginatorItem({
          label: "<",
          page: collection.currentPage - 1,
          className: collection.currentPage > collection.firstPage ? undefined : "disabled",
          collection: collection
        });

        var gotoNext = new PaginatorItem({
          label: ">",
          page: collection.currentPage + 1,
          className: collection.currentPage < collection.totalPages ? undefined : "disabled",
          collection: collection
        });

        var gotoLast = new PaginatorItem({
          label: ">>",
          page: collection.totalPages,
          className: collection.currentPage < collection.totalPages ? undefined : "disabled",
          collection: collection
        });

        this.items.unshift(gotoPrev);
        this.items.unshift(gotoFirst);
        this.items.push(gotoNext);
        this.items.push(gotoLast);
        $ul.prepend(gotoPrev.render().$el);
        $ul.prepend(gotoFirst.render().$el);
        $ul.append(gotoNext.render().$el);
        $ul.append(gotoLast.render().$el);
      }
    },

    render: function () {
      var renderableColCount = _.reduce(
        this.columns.pluck("renderable"),
        function (accum, renderable) {
          return renderable ? accum + 1 : 0;
        }, 0);
      this.$el.append($("

"));
      this.refresh();
      return this;
    }

  });

}(jQuery, _, Backbone, Backgrid));
<commit_msg>massive commit of documentations and bugfixes<commit_after>/*
  backgrid-paginator
  http://github.com/wyuenho/backgrid

  Copyright (c) 2012 Jimmy Yuen Ho Wong
  Licensed under the MIT @license.
*/

// TODO: refactor this

(function ($, _, Backbone, Backgrid) {

  var PaginatorItem = Backgrid.PaginatorItem = Backbone.View.extend({

    tagName: "li",

    events: {
      "click a": "loadPage"
    },

    initialize: function (options) {
      this.label = options.label;
      this.page = options.page;
      this.hasAnchor = typeof options.hasAnchor !== "undefined" ? options.hasAnchor : true;
    },

    render: function () {
      var $a = $("" + this.label + "", {
        href: "#",
        title: "Page " + this.label
      });
      this.$el.append($a);

      return this;
    },

    loadPage: function (e) {
      e.preventDefault();
      if (!this.$el.hasClass("active") && !this.$el.hasClass('disabled')) {
        this.collection.goTo(this.page);
      }
    }

  });

  var Paginator = Backgrid.Paginator = Backgrid.Footer.extend({

    className: "paginator",

    windowSize: 10,
    hasFastForward: true,

    initialize: function (options) {
      Backgrid.Footer.prototype.initialize.apply(this, arguments);
      options = options ? _.clone(options) : {};
      this.collection.on("reset", this.refresh, this);
      this.windowSize = options.windowSize || this.windowSize;
      this.hasFastForward = options.hasFastForward || this.hasFastForward;
      this.items = [];
    },

    dispose: function () {
      if (this.parent && this.parent.off) this.parent.off(null, null, this);
      this.columns.off(null, null, this);
      var item = null;
      for (var i = 0; i < this.items.length; i++) {
        item = this.items[i];
        item.off(null, null, this);
        item.dispose();
      }
      return Backbone.View.prototype.dispose.apply(this, arguments);
    },

    refresh: function () {
      var $ul = this.$el.find("ul");

      for (var i = 0; i < this.items.length; i++) {
        this.items[i].remove();
      }
      this.items = [];

      var collection = this.collection;

      // 0-based here
      var lastPage = collection.totalPages;
      var windowStart = Math.floor((collection.currentPage - 1) / this.windowSize) * this.windowSize;
      var windowEnd = windowStart + this.windowSize;
      windowEnd = windowEnd <= lastPage ? windowEnd : lastPage;
      for (var i = windowStart; i < windowEnd; i++) {
        // render link if not at current page
        var item = new PaginatorItem({
          label: i + 1,
          page: i + 1,
          className: i + 1 === collection.currentPage ? "active" : undefined,
          collection: collection
        });
        this.items.push(item);
        $ul.append(item.render().$el);
      }

      this.renderFastForward();
    },

    renderFastForward: function () {
      if (this.hasFastForward) {

        var $ul = this.$el.find("ul");
        var collection = this.collection;

        var gotoFirst = new PaginatorItem({
          label: "《",
          page: 1,
          className: collection.currentPage > collection.firstPage ? undefined : "disabled",
          collection: collection
        });

        var gotoPrev = new PaginatorItem({
          label: "〈",
          page: collection.currentPage - 1,
          className: collection.currentPage > collection.firstPage ? undefined : "disabled",
          collection: collection
        });

        var gotoNext = new PaginatorItem({
          label: "〉",
          page: collection.currentPage + 1,
          className: collection.currentPage < collection.totalPages ? undefined : "disabled",
          collection: collection
        });

        var gotoLast = new PaginatorItem({
          label: "》",
          page: collection.totalPages,
          className: collection.currentPage < collection.totalPages ? undefined : "disabled",
          collection: collection
        });

        this.items.unshift(gotoPrev);
        this.items.unshift(gotoFirst);
        this.items.push(gotoNext);
        this.items.push(gotoLast);
        $ul.prepend(gotoPrev.render().$el);
        $ul.prepend(gotoFirst.render().$el);
        $ul.append(gotoNext.render().$el);
        $ul.append(gotoLast.render().$el);
      }
    },

    render: function () {
      var renderableColCount = _.reduce(
        this.columns.pluck("renderable"),
        function (accum, renderable) {
          return renderable ? accum + 1 : 0;
        }, 0);
      this.$el.append($("

"));
      this.refresh();
      return this;
    }

  });

}(jQuery, _, Backbone, Backgrid));
<|endoftext|>


<commit_before>import PopperJS from './popper';
import { PopupManager } from 'vue-popup';

/**
 * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper.
 * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper.
 * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -right), left(-start, -end)
 * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative).
 * @param {Boolean} [visible=false] Visibility of the popup element.
 * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style.
 */
export default {
  props: {
    placement: {
      type: String,
      default: 'bottom'
    },
    boundariesPadding: {
      type: Number,
      default: 5
    },
    reference: {},
    popper: {},
    offset: {
      default: 0
    },
    value: Boolean,
    visibleArrow: Boolean,
    transition: String,
    appendToBody: {
      type: Boolean,
      default: true
    },
    options: {
      type: Object,
      default() {
        return {
          gpuAcceleration: false
        };
      }
    }
  },

  data() {
    return {
      showPopper: false
    };
  },

  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.showPopper = val;
        this.$emit('input', val);
      }
    },

    showPopper(val) {
      val ? this.updatePopper() : this.destroyPopper();
      this.$emit('input', val);
    }
  },

  methods: {
    createPopper() {
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
        return;
      }

      const options = this.options;
      const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper;
      let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference;

      if (!reference &&
          this.$slots.reference &&
          this.$slots.reference[0]) {
        reference = this.referenceElm = this.$slots.reference[0].elm;
      }
      if (!popper || !reference) return;
      if (this.visibleArrow) this.appendArrow(popper);
      if (this.appendToBody) document.body.appendChild(this.popperElm);
      if (this.popperJS && this.popperJS.destroy) {
        this.popperJS.destroy();
      }

      options.placement = this.placement;
      options.offset = this.offset;
      this.popperJS = new PopperJS(reference, popper, options);
      this.popperJS.onCreate(_ => {
        this.$emit('created', this);
        this.resetTransformOrigin();
        this.$nextTick(this.updatePopper);
      });
      this.popperJS._popper.style.zIndex = PopupManager.nextZIndex();
    },

    updatePopper() {
      this.popperJS ? this.popperJS.update() : this.createPopper();
    },

    doDestroy() {
      /* istanbul ignore if */
      if (this.showPopper || !this.popperJS) return;
      this.popperJS.destroy();
      this.popperJS = null;
    },

    destroyPopper() {
      if (this.popperJS) {
        this.resetTransformOrigin();
      }
    },

    resetTransformOrigin() {
      let placementMap = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
      let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1
        ? `center ${ origin }`
        : `${ origin } center`;
    },

    appendArrow(element) {
      let hash;
      if (this.appended) {
        return;
      }

      this.appended = true;

      for (let item in element.attributes) {
        if (/^_v-/.test(element.attributes[item].name)) {
          hash = element.attributes[item].name;
          break;
        }
      }

      const arrow = document.createElement('div');

      if (hash) {
        arrow.setAttribute(hash, '');
      }
      arrow.setAttribute('x-arrow', '');
      arrow.className = 'popper__arrow';
      element.appendChild(arrow);
    }
  },

  beforeDestroy() {
    this.doDestroy();
    this.popperElm &&
    document.body.contains(this.popperElm) &&
    document.body.removeChild(this.popperElm);
  }
};
<commit_msg>vue-popper: fix a node removal bug (#617)<commit_after>import PopperJS from './popper';
import { PopupManager } from 'vue-popup';

/**
 * @param {HTMLElement} [reference=$refs.reference] - The reference element used to position the popper.
 * @param {HTMLElement} [popper=$refs.popper] - The HTML element used as popper, or a configuration used to generate the popper.
 * @param {String} [placement=button] - Placement of the popper accepted values: top(-start, -end), right(-start, -end), bottom(-start, -right), left(-start, -end)
 * @param {Number} [offset=0] - Amount of pixels the popper will be shifted (can be negative).
 * @param {Boolean} [visible=false] Visibility of the popup element.
 * @param {Boolean} [visible-arrow=false] Visibility of the arrow, no style.
 */
export default {
  props: {
    placement: {
      type: String,
      default: 'bottom'
    },
    boundariesPadding: {
      type: Number,
      default: 5
    },
    reference: {},
    popper: {},
    offset: {
      default: 0
    },
    value: Boolean,
    visibleArrow: Boolean,
    transition: String,
    appendToBody: {
      type: Boolean,
      default: true
    },
    options: {
      type: Object,
      default() {
        return {
          gpuAcceleration: false
        };
      }
    }
  },

  data() {
    return {
      showPopper: false
    };
  },

  watch: {
    value: {
      immediate: true,
      handler(val) {
        this.showPopper = val;
        this.$emit('input', val);
      }
    },

    showPopper(val) {
      val ? this.updatePopper() : this.destroyPopper();
      this.$emit('input', val);
    }
  },

  methods: {
    createPopper() {
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
        return;
      }

      const options = this.options;
      const popper = this.popperElm = this.popperElm || this.popper || this.$refs.popper;
      let reference = this.referenceElm = this.referenceElm || this.reference || this.$refs.reference;

      if (!reference &&
          this.$slots.reference &&
          this.$slots.reference[0]) {
        reference = this.referenceElm = this.$slots.reference[0].elm;
      }
      if (!popper || !reference) return;
      if (this.visibleArrow) this.appendArrow(popper);
      if (this.appendToBody) document.body.appendChild(this.popperElm);
      if (this.popperJS && this.popperJS.destroy) {
        this.popperJS.destroy();
      }

      options.placement = this.placement;
      options.offset = this.offset;
      this.popperJS = new PopperJS(reference, popper, options);
      this.popperJS.onCreate(_ => {
        this.$emit('created', this);
        this.resetTransformOrigin();
        this.$nextTick(this.updatePopper);
      });
      this.popperJS._popper.style.zIndex = PopupManager.nextZIndex();
    },

    updatePopper() {
      this.popperJS ? this.popperJS.update() : this.createPopper();
    },

    doDestroy() {
      /* istanbul ignore if */
      if (this.showPopper || !this.popperJS) return;
      this.popperJS.destroy();
      this.popperJS = null;
    },

    destroyPopper() {
      if (this.popperJS) {
        this.resetTransformOrigin();
      }
    },

    resetTransformOrigin() {
      let placementMap = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
      let placement = this.popperJS._popper.getAttribute('x-placement').split('-')[0];
      let origin = placementMap[placement];
      this.popperJS._popper.style.transformOrigin = ['top', 'bottom'].indexOf(placement) > -1
        ? `center ${ origin }`
        : `${ origin } center`;
    },

    appendArrow(element) {
      let hash;
      if (this.appended) {
        return;
      }

      this.appended = true;

      for (let item in element.attributes) {
        if (/^_v-/.test(element.attributes[item].name)) {
          hash = element.attributes[item].name;
          break;
        }
      }

      const arrow = document.createElement('div');

      if (hash) {
        arrow.setAttribute(hash, '');
      }
      arrow.setAttribute('x-arrow', '');
      arrow.className = 'popper__arrow';
      element.appendChild(arrow);
    }
  },

  beforeDestroy() {
    this.doDestroy();
    this.popperElm &&
    this.popperElm.parentNode === document.body &&
    document.body.removeChild(this.popperElm);
  }
};
<|endoftext|>


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

const $$ = require('gulp-load-plugins')();
const babel = require('babelify');
const browserify = require('browserify');
const buffer = require('vinyl-buffer');
const closureCompile = require('./closure-compile').closureCompile;
const fs = require('fs-extra');
const glob = require('glob');
const gulp = $$.help(require('gulp'));
const jsifyCssAsync = require('./jsify-css').jsifyCssAsync;
const lazypipe = require('lazypipe');
const minimist = require('minimist');
const pathLib = require('path');
const resolveConfig = require('./compile-config').resolveConfig;
const source = require('vinyl-source-stream');
const touch = require('touch');
const watchify = require('watchify');
const internalRuntimeVersion = require('./internal-version').VERSION;
const argv = require('minimist')(process.argv.slice(2));

function distAssets() {
  mkdirSync('dist');
  fs.copySync('assets/loader.svg', 'dist/loader.svg', {overwrite: true});
  return compileCss('assets/swg-button.css', 'dist/swg-button.css', {
    sourceMap: false,
  }).then(() => {
    mkdirSync('dist/i18n');
    fs.copySync('assets/i18n/', 'dist/i18n/', {overwrite: true});
  });
}

/**
 * Compile all the css and drop in the build folder.
 *
 * @param {string} srcFile Source file.
 * @param {string} outputFile Destination file.
 * @param {?Object} options
 * @return {!Promise}
 */
function compileCss(srcFile, outputFile, options) {
  options = options || {};

  if (options.watch) {
    $$.watch(srcFile, function() {
      compileCss(srcFile, outputFile,
          Object.assign({}, options, {watch: false}));
    });
  }

  const startTime = Date.now();
  return jsifyCssAsync(srcFile, options).then(css => {
    mkdirSync(pathLib.dirname(outputFile));
    fs.writeFileSync(outputFile, css);
  }).then(() => {
    endBuildStep('Recompiled CSS', '', startTime);
  });
}

/**
 * Stops the timer for the given build step and prints the execution time,
 * unless we are on Travis.
 * @param {string} stepName Name of the action, like 'Compiled' or 'Minified'
 * @param {string} targetName Name of the target, like a filename or path
 * @param {DOMHighResTimeStamp} startTime Start time of build step
 */
function endBuildStep(stepName, targetName, startTime) {
  const endTime = Date.now();
  const executionTime = new Date(endTime - startTime);
  const secs = executionTime.getSeconds();
  const ms = executionTime.getMilliseconds().toString();
  let timeString = '(';
  if (secs === 0) {
    timeString += ms + ' ms)';
  } else {
    timeString += secs + '.' + ms + ' s)';
  }
  if (!process.env.TRAVIS) {
    $$.log(
        stepName,
        $$.colors.cyan(targetName),
        $$.colors.green(timeString));
  }
}

function mkdirSync(path) {
  try {
    fs.mkdirSync(path);
  } catch (e) {
    if (e.code != 'EEXIST') {
      throw e;
    }
  }
}

distAssets.description = 'Prepare assets';
gulp.task('assets', distAssets);
<commit_msg>clean up gulp assets<commit_after>/**
 * Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const $$ = require('gulp-load-plugins')();
const colors = require('ansi-colors');
const fs = require('fs-extra');
const gulp = $$.help(require('gulp'));
const log = require('fancy-log');
const jsifyCssAsync = require('./jsify-css').jsifyCssAsync;
const pathLib = require('path');

function distAssets() {
  mkdirSync('dist');
  fs.copySync('assets/loader.svg', 'dist/loader.svg', {overwrite: true});
  return compileCss('assets/swg-button.css', 'dist/swg-button.css', {
    sourceMap: false,
  }).then(() => {
    mkdirSync('dist/i18n');
    fs.copySync('assets/i18n/', 'dist/i18n/', {overwrite: true});
  });
}

/**
 * Compile all the css and drop in the build folder.
 *
 * @param {string} srcFile Source file.
 * @param {string} outputFile Destination file.
 * @param {?Object} options
 * @return {!Promise}
 */
function compileCss(srcFile, outputFile, options) {
  options = options || {};

  if (options.watch) {
    $$.watch(srcFile, function() {
      compileCss(srcFile, outputFile,
          Object.assign({}, options, {watch: false}));
    });
  }

  const startTime = Date.now();
  return jsifyCssAsync(srcFile, options).then(css => {
    mkdirSync(pathLib.dirname(outputFile));
    fs.writeFileSync(outputFile, css);
  }).then(() => {
    endBuildStep('Recompiled CSS', '', startTime);
  });
}

/**
 * Stops the timer for the given build step and prints the execution time,
 * unless we are on Travis.
 * @param {string} stepName Name of the action, like 'Compiled' or 'Minified'
 * @param {string} targetName Name of the target, like a filename or path
 * @param {DOMHighResTimeStamp} startTime Start time of build step
 */
function endBuildStep(stepName, targetName, startTime) {
  const endTime = Date.now();
  const executionTime = new Date(endTime - startTime);
  const secs = executionTime.getSeconds();
  const ms = executionTime.getMilliseconds().toString();
  let timeString = '(';
  if (secs === 0) {
    timeString += ms + ' ms)';
  } else {
    timeString += secs + '.' + ms + ' s)';
  }
  if (!process.env.TRAVIS) {
    log(
        stepName,
        colors.cyan(targetName),
        colors.green(timeString));
  }
}

function mkdirSync(path) {
  try {
    fs.mkdirSync(path);
  } catch (e) {
    if (e.code != 'EEXIST') {
      throw e;
    }
  }
}

distAssets.description = 'Prepare assets';
gulp.task('assets', distAssets);
<|endoftext|>


<commit_before>import * as path from 'path';

import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import SystemBellPlugin from 'system-bell-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
import merge from 'webpack-merge';

const pkg = require('./package.json');

const TARGET = process.env.npm_lifecycle_event || '';
const ROOT_PATH = __dirname;
const config = {
  paths: {
    readme: path.join(ROOT_PATH, 'README.md'),
    dist: path.join(ROOT_PATH, 'dist'),
    src: path.join(ROOT_PATH, 'src'),
    docs: path.join(ROOT_PATH, 'docs')
  },
  filename: 'boilerplate',
  library: 'Boilerplate'
};

process.env.BABEL_ENV = TARGET;

const common = {
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.png', '.jpg']
  },
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        include: [
          config.paths.docs,
          config.paths.src
        ]
      }
    ],
    loaders: [
      {
        test: /\.md$/,
        loaders: ['catalog/lib/loader', 'raw']
      },
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
        include: config.paths.docs
      },
      {
        test: /\.jpg$/,
        loader: 'file',
        include: config.paths.docs
      },
      {
        test: /\.json$/,
        loader: 'json',
        include: path.join(ROOT_PATH, 'package.json')
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

const siteCommon = {
  plugins: [
    new HtmlWebpackPlugin({
      template: require('html-webpack-template'), // eslint-disable-line global-require
      inject: false,
      mobile: true,
      title: pkg.name,
      appMountId: 'app'
    }),
    new webpack.DefinePlugin({
      NAME: JSON.stringify(pkg.name),
      USER: JSON.stringify(pkg.user),
      VERSION: JSON.stringify(pkg.version)
    })
  ]
};

if (TARGET === 'start') {
  module.exports = merge(common, siteCommon, {
    devtool: 'eval-source-map',
    entry: {
      docs: [config.paths.docs]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"development"'
      }),
      new webpack.HotModuleReplacementPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loaders: ['style', 'css']
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel?cacheDirectory'],
          include: [
            config.paths.docs,
            config.paths.src
          ]
        }
      ]
    },
    devServer: {
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,
      host: process.env.HOST,
      port: process.env.PORT,
      stats: 'errors-only'
    }
  });
}

if (TARGET === 'gh-pages' || TARGET === 'gh-pages:stats') {
  module.exports = merge(common, siteCommon, {
    entry: {
      app: config.paths.docs,
      vendors: [
        'react',
        'react-dom'
      ]
    },
    output: {
      path: './gh-pages',
      filename: '[name].[chunkhash].js',
      chunkFilename: '[chunkhash].js'
    },
    plugins: [
      new CleanWebpackPlugin(['gh-pages'], {
        verbose: false
      }),
      new ExtractTextPlugin('[name].[chunkhash].css'),
      new webpack.DefinePlugin({
          // This affects the react lib size
        'process.env.NODE_ENV': '"production"'
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      }),
      new webpack.optimize.CommonsChunkPlugin(
        'vendor',
        '[name].[chunkhash].js'
      )
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css')
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.docs,
            config.paths.src
          ]
        }
      ]
    }
  });
}

const distCommon = {
  devtool: 'source-map',
  output: {
    path: config.paths.dist,
    libraryTarget: 'umd',
    library: config.library
  },
  entry: config.paths.src,
  externals: {
    react: {
      commonjs: 'react',
      commonjs2: 'react',
      amd: 'React',
      root: 'React'
    }
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel'],
        include: config.paths.src
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'dist') {
  module.exports = merge(distCommon, {
    output: {
      filename: `${config.filename}.js`
    }
  });
}

if (TARGET === 'dist:min') {
  module.exports = merge(distCommon, {
    output: {
      filename: `${config.filename}.min.js`
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

if (!TARGET) {
  module.exports = common;
}
<commit_msg>Drop unused path<commit_after>import * as path from 'path';

import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import SystemBellPlugin from 'system-bell-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
import merge from 'webpack-merge';

const pkg = require('./package.json');

const TARGET = process.env.npm_lifecycle_event || '';
const ROOT_PATH = __dirname;
const config = {
  paths: {
    dist: path.join(ROOT_PATH, 'dist'),
    src: path.join(ROOT_PATH, 'src'),
    docs: path.join(ROOT_PATH, 'docs')
  },
  filename: 'boilerplate',
  library: 'Boilerplate'
};

process.env.BABEL_ENV = TARGET;

const common = {
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.png', '.jpg']
  },
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        include: [
          config.paths.docs,
          config.paths.src
        ]
      }
    ],
    loaders: [
      {
        test: /\.md$/,
        loaders: ['catalog/lib/loader', 'raw']
      },
      {
        test: /\.png$/,
        loader: 'url?limit=100000&mimetype=image/png',
        include: config.paths.docs
      },
      {
        test: /\.jpg$/,
        loader: 'file',
        include: config.paths.docs
      },
      {
        test: /\.json$/,
        loader: 'json',
        include: path.join(ROOT_PATH, 'package.json')
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

const siteCommon = {
  plugins: [
    new HtmlWebpackPlugin({
      template: require('html-webpack-template'), // eslint-disable-line global-require
      inject: false,
      mobile: true,
      title: pkg.name,
      appMountId: 'app'
    }),
    new webpack.DefinePlugin({
      NAME: JSON.stringify(pkg.name),
      USER: JSON.stringify(pkg.user),
      VERSION: JSON.stringify(pkg.version)
    })
  ]
};

if (TARGET === 'start') {
  module.exports = merge(common, siteCommon, {
    devtool: 'eval-source-map',
    entry: {
      docs: [config.paths.docs]
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"development"'
      }),
      new webpack.HotModuleReplacementPlugin()
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loaders: ['style', 'css']
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel?cacheDirectory'],
          include: [
            config.paths.docs,
            config.paths.src
          ]
        }
      ]
    },
    devServer: {
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,
      host: process.env.HOST,
      port: process.env.PORT,
      stats: 'errors-only'
    }
  });
}

if (TARGET === 'gh-pages' || TARGET === 'gh-pages:stats') {
  module.exports = merge(common, siteCommon, {
    entry: {
      app: config.paths.docs,
      vendors: [
        'react',
        'react-dom'
      ]
    },
    output: {
      path: './gh-pages',
      filename: '[name].[chunkhash].js',
      chunkFilename: '[chunkhash].js'
    },
    plugins: [
      new CleanWebpackPlugin(['gh-pages'], {
        verbose: false
      }),
      new ExtractTextPlugin('[name].[chunkhash].css'),
      new webpack.DefinePlugin({
          // This affects the react lib size
        'process.env.NODE_ENV': '"production"'
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      }),
      new webpack.optimize.CommonsChunkPlugin(
        'vendor',
        '[name].[chunkhash].js'
      )
    ],
    module: {
      loaders: [
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css')
        },
        {
          test: /\.jsx?$/,
          loaders: ['babel'],
          include: [
            config.paths.docs,
            config.paths.src
          ]
        }
      ]
    }
  });
}

const distCommon = {
  devtool: 'source-map',
  output: {
    path: config.paths.dist,
    libraryTarget: 'umd',
    library: config.library
  },
  entry: config.paths.src,
  externals: {
    react: {
      commonjs: 'react',
      commonjs2: 'react',
      amd: 'React',
      root: 'React'
    }
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loaders: ['babel'],
        include: config.paths.src
      }
    ]
  },
  plugins: [
    new SystemBellPlugin()
  ]
};

if (TARGET === 'dist') {
  module.exports = merge(distCommon, {
    output: {
      filename: `${config.filename}.js`
    }
  });
}

if (TARGET === 'dist:min') {
  module.exports = merge(distCommon, {
    output: {
      filename: `${config.filename}.min.js`
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

if (!TARGET) {
  module.exports = common;
}
<|endoftext|>