<commit_before>const path = require('path');

const PATHS = {
  app: path.join(__dirname, 'app'),
  dist: path.join(__dirname, 'dist')
};

module.exports = {
  entry: ['babel-polyfill', './js/main.js'],
  output: {
    path: path.join(PATHS.dist, 'js'),
    publicPath: '/js/',
    filename: "bundle.js"
  },
  devtool: 'source-map',
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        // define an include so we check just the files we need
        include: PATHS.app
      }
    ],
    loaders: [
      { test: /\.css$/, loader: "style!css" },
      {
	    test: /\.jsx?$/,
	    loader: 'babel',
        query: {
          cacheDirectory: true,
          presets:[ 'es2015', 'react', 'stage-3' ]
        }
      }
    ]
  }
};
<commit_msg>Update Webpack preset list<commit_after>const path = require('path');

const PATHS = {
  app: path.join(__dirname, 'app'),
  dist: path.join(__dirname, 'dist')
};

module.exports = {
  entry: ['babel-polyfill', './js/main.js'],
  output: {
    path: path.join(PATHS.dist, 'js'),
    publicPath: '/js/',
    filename: "bundle.js"
  },
  devtool: 'source-map',
  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loaders: ['eslint'],
        // define an include so we check just the files we need
        include: PATHS.app
      }
    ],
    loaders: [
      { test: /\.css$/, loader: "style!css" },
      {
	    test: /\.jsx?$/,
	    loader: 'babel',
        query: {
          cacheDirectory: true,
          presets:[ 'es2015', 'react', 'stage-2' ]
        }
      }
    ]
  }
};
<|endoftext|>


<commit_before>/* file: controller-book.js */
/*!
 * Copyright 2017 ikarus512
 * https://github.com/ikarus512/fcc1.git
 */

;( function() {
  'use strict';

  angular.module('myapp')

  .controller('myApp4ControllerBook', [
    '$scope', '$window', '$timeout', 'bookStorage', 'WebSocketService', 'MyError',
    function ($scope, $window, $timeout, bookStorage, WebSocketService, MyError) {

      $scope.init = function(logintype,uid,username,bookId) {
        $scope.logintype = logintype==='undefined' ? '' : logintype;
        $scope.uid = uid==='undefined' ? '' : uid;
        $scope.username = username==='undefined' ? '' : username;
        $scope.bookId = bookId==='undefined' ? '' : bookId;
        bookRefresh();
      };

      bookRefresh();

      function bookRefresh(noreset) {

        $scope.bidIdx = -1;

        if ($scope.bookId) {

          bookStorage.getBook($scope.bookId)

          .then( function(res) {
            var cur = $scope.curBook;
            var curBook = res.data;

            // description: show more/show less
            if (curBook) {
              var s = String(curBook.description);
              if (s.length > 200) {
                curBook.descriptionShort = s.substr(0, 200);
                curBook.short = true;
              }
            }

            // Filter bids
            if (curBook.bids) {

              // Filter bid.msgs
              curBook.bids.forEach( function(bid) {
                if (!bid.msgs) bid.msgs = [];
                // bid.msgs.forEach( function(msg) {
                //   msg.time = new Date(msg.time);
                // });
              });

              // Prepare bid price for update
              curBook.bids.forEach( function(bid) { bid.updateBidPrice = bid.price; });

              // Check if user has bid
              curBook.hasBid = curBook.bids.some( function(bid,idx) {
                var found = bid.by._id === $scope.uid;
                if (found) {
                  $scope.bidIdx = idx;
                }
                return found;
              });
            }

            // Error messages processing for updating price
            if ($scope.bidIdx >= 0) {

              var priceRequiredId = '#priceRequired'+$scope.bidIdx,
                priceMinId = '#priceMin'+$scope.bidIdx,
                priceNumberId = '#priceNumber'+$scope.bidIdx,
                popoverIds = [priceRequiredId, priceMinId, priceNumberId];

              if ($scope.clearPreviousWatch) {
                $scope.clearPreviousWatch();

                // Destroy popovers
                popoverIds.forEach( function(id) { $(id).popover('destroy'); });
              }

              // Init popovers
              popoverIds.forEach( function(id) { $(id).popover(); });

              // Hide/show popovers
              $scope.clearPreviousWatch =
                $scope.$watch(
                  'updateBidForm[\'price'+$scope.bidIdx+'\'].$error',
                  function(newData, oldData) {

                    if (!(oldData && oldData.required) && newData && newData.required) {
                      $(priceRequiredId).popover('show');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('hide');
                    }

                    if (!(oldData && oldData.min) && newData && newData.min) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('show');
                      $(priceNumberId)  .popover('hide');
                    }

                    if (!(oldData && oldData.number) && newData && newData.number) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('show');
                    }

                    if (newData && !newData.required && !newData.min && !newData.number) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('hide');
                    }

                  },
                  true
                ); // scope.$watch('data',...)
            }

            $scope.curBook = curBook;

            if(!noreset) $scope.bookCancelChanges(); // reset newBook=curBook
          })

          .catch( function(res) {
            $scope.curBook = null;
            $scope.newBook = null;
            MyError.alert(res);
          })

          .then( function() {
            WebSocketService.subscribe(
              $scope.bookId,
              $scope.uid,
              receiveMessage
            );
          });

        }

      } // function bookRefresh(...)

      $scope.chooseBid = function(bidIdx) {

        if (confirm('Do you really want to finish trade with price $'+
          $scope.curBook.bids[bidIdx].price+'?'))
        {
          bookStorage.chooseBid($scope.curBook._id, $scope.curBook.bids[bidIdx].by._id)
          .then( function(res) { bookRefresh(); })
          .catch( function(res) { MyError.alert(res); });
        }

      }; // $scope.chooseBid = function(...)

      $scope.addBid = function() {

        bookStorage.addBid($scope.curBook._id, $scope.newBidPrice)
        .then( function(res) { bookRefresh(); })
        .catch( function(res) { MyError.alert(res); });

      }; // $scope.addBid = function(...)

      $scope.updateBid = function(curPrice, newPrice) {
        if (curPrice !== newPrice) {
          bookStorage.addBid($scope.curBook._id, newPrice)
          .then( function(res) { bookRefresh(); })
          .catch( function(res) { MyError.alert(res); });
        }
      }; // $scope.updateBid = function(...)

      $scope.bookCancelChanges = function() {

        if ($scope.curBook) {

            $scope.newBook = {};
            $scope.newBook.title        = $scope.curBook.title;
            $scope.newBook._id          = $scope.curBook._id;
            $scope.newBook.price        = $scope.curBook.price;
            $scope.newBook.ownerId      = $scope.curBook.ownerId;
            $scope.newBook.ownerName    = $scope.curBook.ownerName;
            $scope.newBook.keywords     = $scope.curBook.keywords;
            $scope.newBook.description  = $scope.curBook.description;
            $scope.newBook.photoId      = $scope.curBook.photoId;

            $scope.clearFile();

        }

      }; // $scope.bookCancelChanges = function(...)

      $scope.clearFile = function() {
        $scope.myBookEditForm.file.$setValidity("maxSize", true);
        $scope.newBook.file = null;
      };

      $scope.bookSaveChanges = function() {

        $scope.newBook.title = $scope.newBook.title.trim();
        $scope.newBook.keywords = $scope.newBook.keywords.trim();
        $scope.newBook.description = $scope.newBook.description.trim();

        if ($scope.newBook.title) {

          bookStorage.postBook($scope.newBook)

          .then( function(res) {
            bookRefresh();
          })

          .catch( function(res) {
            // Report error during book update
            MyError.alert(res);
          });

        }

      }; // $scope.bookSaveChanges = function(...)

      $scope.bookDelete = function() {

        if ($scope.newBook) {

          if (confirm('Do you really want to delete the book?')) {

            bookStorage.bookDelete($scope.newBook._id)

            .then( function onOk(res) {
              $scope.goBooksPage();
            })

            .catch( function onErr(res) {
              // Report error during poll deletion
              MyError.alert(res);
            });

          }

        }

      }; // $scope.bookDelete = function(...)

      $scope.goBooksPage = function() {
        $window.location.href = '/app4/books'; // return to books page
      }; // $scope.goBooksPage = function(...)

      function receiveMessage(data) {
        var bidId, msgBy;
        if (data.msgtype==='app4-message') {
          if ($scope.curBook.ownerId === data.to) {
            // Message from bidder to book owner
            bidId = data.from;

            var name;
            $scope.curBook.bids.some( function(bid) { name = bid.by.name; return bid.by._id === bidId; });
            msgBy = {_id: data.from, name: name};
          } else {
            // Message from book owner to bidder
            bidId = data.to;
            msgBy = {_id: data.from, name: $scope.curBook.ownerName};
          }

          // Filter bid.msgs
          var bidIdx;
          var found = $scope.curBook.bids.some( function(bid,idx) {
            bidIdx = idx;
            return bid.by._id === bidId;
          });
          if (found) {
            var msg = {
              by: msgBy,
              at: data.time,
              text: data.text,
            };
            $scope.curBook.bids[bidIdx].msgs.push(msg);
            $scope.$apply();
          }

        }
      }

      $scope.sendMsg = function(bid, from, to) {
        if (bid.newMsg) {
          var msg = {
            by: {_id: $scope.uid, name: $scope.username},
            at: new Date(),
            text: bid.newMsg,
          };
          WebSocketService.sendMessage($scope.curBook._id,from,to,new Date(),bid.newMsg)
          bid.msgs.push(msg);
          bid.newMsg = '';
        }
      }; // $scope.sendMsg = function(...)

  }]); // .controller('myApp4ControllerBook', ...

})();
<commit_msg>cosmetic<commit_after>/* file: controller-book.js */
/*!
 * Copyright 2017 ikarus512
 * https://github.com/ikarus512/fcc1.git
 */

;( function() {
  'use strict';

  angular.module('myapp')

  .controller('myApp4ControllerBook', [
    '$scope', '$window', '$timeout', 'bookStorage', 'WebSocketService', 'MyError',
    function ($scope, $window, $timeout, bookStorage, WebSocketService, MyError) {

      $scope.init = function(logintype,uid,username,bookId) {
        $scope.logintype = logintype==='undefined' ? '' : logintype;
        $scope.uid = uid==='undefined' ? '' : uid;
        $scope.username = username==='undefined' ? '' : username;
        $scope.bookId = bookId==='undefined' ? '' : bookId;
        bookRefresh();
      };

      bookRefresh();

      function bookRefresh(noreset) {

        $scope.bidIdx = -1;

        if ($scope.bookId) {

          bookStorage.getBook($scope.bookId)

          .then( function(res) {
            var cur = $scope.curBook;
            var curBook = res.data;

            // description: show more/show less
            if (curBook) {
              var s = String(curBook.description);
              if (s.length > 200) {
                curBook.descriptionShort = s.substr(0, 200);
                curBook.short = true;
              }
            }

            // Filter bids
            if (curBook.bids) {

              // Filter bid.msgs
              curBook.bids.forEach( function(bid) {
                if (!bid.msgs) bid.msgs = [];
                // bid.msgs.forEach( function(msg) {
                //   msg.time = new Date(msg.time);
                // });
              });

              // Prepare bid price for update
              curBook.bids.forEach( function(bid) { bid.updateBidPrice = bid.price; });

              // Check if user has bid
              curBook.hasBid = curBook.bids.some( function(bid,idx) {
                var found = bid.by._id === $scope.uid;
                if (found) {
                  $scope.bidIdx = idx;
                }
                return found;
              });
            }

            // Error messages processing for updating price
            if ($scope.bidIdx >= 0) {

              var priceRequiredId = '#priceRequired'+$scope.bidIdx,
                priceMinId = '#priceMin'+$scope.bidIdx,
                priceNumberId = '#priceNumber'+$scope.bidIdx,
                popoverIds = [priceRequiredId, priceMinId, priceNumberId];

              if ($scope.clearPreviousWatch) {
                $scope.clearPreviousWatch();

                // Destroy popovers
                popoverIds.forEach( function(id) { $(id).popover('destroy'); });
              }

              // Init popovers
              popoverIds.forEach( function(id) { $(id).popover(); });

              // Hide/show popovers
              $scope.clearPreviousWatch =
                $scope.$watch(
                  'updateBidForm[\'price'+$scope.bidIdx+'\'].$error',
                  function(newData, oldData) {

                    if (!(oldData && oldData.required) && newData && newData.required) {
                      $(priceRequiredId).popover('show');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('hide');
                    }

                    if (!(oldData && oldData.min) && newData && newData.min) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('show');
                      $(priceNumberId)  .popover('hide');
                    }

                    if (!(oldData && oldData.number) && newData && newData.number) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('show');
                    }

                    if (newData && !newData.required && !newData.min && !newData.number) {
                      $(priceRequiredId).popover('hide');
                      $(priceMinId)     .popover('hide');
                      $(priceNumberId)  .popover('hide');
                    }

                  },
                  true
                ); // scope.$watch('data',...)
            }

            $scope.curBook = curBook;

            if(!noreset) $scope.bookCancelChanges(); // reset newBook=curBook
          })

          .catch( function(res) {
            $scope.curBook = null;
            $scope.newBook = null;
            MyError.alert(res);
          })

          .then( function() {
            WebSocketService.subscribe(
              $scope.bookId,
              $scope.uid,
              receiveMessage
            );
          });

        }

      } // function bookRefresh(...)

      $scope.chooseBid = function(bidIdx) {

        if (confirm('Do you really want to finish trade with price $'+
          $scope.curBook.bids[bidIdx].price+'?'))
        {
          bookStorage.chooseBid($scope.curBook._id, $scope.curBook.bids[bidIdx].by._id)
          .then( function(res) { bookRefresh(); })
          .catch( function(res) { MyError.alert(res); });
        }

      }; // $scope.chooseBid = function(...)

      $scope.addBid = function() {

        bookStorage.addBid($scope.curBook._id, $scope.newBidPrice)
        .then( function(res) { bookRefresh(); })
        .catch( function(res) { MyError.alert(res); });

      }; // $scope.addBid = function(...)

      $scope.updateBid = function(curPrice, newPrice) {
        if (curPrice !== newPrice) {
          bookStorage.addBid($scope.curBook._id, newPrice)
          .then( function(res) { bookRefresh(); })
          .catch( function(res) { MyError.alert(res); });
        }
      }; // $scope.updateBid = function(...)

      $scope.bookCancelChanges = function() {

        if ($scope.curBook) {

            $scope.newBook = {};
            $scope.newBook.title        = $scope.curBook.title;
            $scope.newBook._id          = $scope.curBook._id;
            $scope.newBook.price        = $scope.curBook.price;
            $scope.newBook.ownerId      = $scope.curBook.ownerId;
            $scope.newBook.ownerName    = $scope.curBook.ownerName;
            $scope.newBook.keywords     = $scope.curBook.keywords;
            $scope.newBook.description  = $scope.curBook.description;
            $scope.newBook.photoId      = $scope.curBook.photoId;

            $scope.clearFile();

        }

      }; // $scope.bookCancelChanges = function(...)

      $scope.clearFile = function() {
        $scope.myBookEditForm.file.$setValidity("maxSize", true);
        $scope.newBook.file = null;
      };

      $scope.bookSaveChanges = function() {

        $scope.newBook.title = $scope.newBook.title.trim();
        $scope.newBook.keywords = $scope.newBook.keywords.trim();
        $scope.newBook.description = $scope.newBook.description.trim();

        if ($scope.newBook.title) {

          bookStorage.postBook($scope.newBook)

          .then( function(res) {
            bookRefresh();
          })

          .catch( function(res) {
            // Report error during book update
            MyError.alert(res);
          });

        }

      }; // $scope.bookSaveChanges = function(...)

      $scope.bookDelete = function() {

        if ($scope.newBook) {

          if (confirm('Do you really want to delete the book?')) {

            bookStorage.bookDelete($scope.newBook._id)

            .then( function onOk(res) {
              $scope.goBooksPage();
            })

            .catch( function onErr(res) {
              // Report error during poll deletion
              MyError.alert(res);
            });

          }

        }

      }; // $scope.bookDelete = function(...)

      $scope.goBooksPage = function() {
        $window.location.href = '/app4/books'; // return to books page
      }; // $scope.goBooksPage = function(...)

      function receiveMessage(data) {
        var bidId, msgBy;
        if (data.msgtype==='app4-message') {
          if ($scope.curBook.ownerId === data.to) {
            // Message from bidder to book owner
            bidId = data.from;

            var name;
            $scope.curBook.bids.some( function(bid) { name = bid.by.name; return bid.by._id === bidId; });
            msgBy = {_id: data.from, name: name};
          } else {
            // Message from book owner to bidder
            bidId = data.to;
            msgBy = {_id: data.from, name: $scope.curBook.ownerName};
          }

          // Filter bid.msgs
          var bidIdx;
          var found = $scope.curBook.bids.some( function(bid,idx) {
            bidIdx = idx;
            return bid.by._id === bidId;
          });
          if (found) {
            var msg = {
              by: msgBy,
              at: data.time,
              text: data.text,
            };
            $scope.curBook.bids[bidIdx].msgs.push(msg);
            $scope.$apply();
          }

        }
      }

      $scope.sendMsg = function(bid, from, to) {
        if (bid.newMsg) {
          var msg = {
            by: {_id: $scope.uid, name: $scope.username},
            at: new Date(),
            text: bid.newMsg,
          };
          WebSocketService.sendMessage($scope.curBook._id,from,to,new Date(),bid.newMsg);
          bid.msgs.push(msg);
          bid.newMsg = '';
        }
      }; // $scope.sendMsg = function(...)

  }]); // .controller('myApp4ControllerBook', ...

})();
<|endoftext|>


<commit_before>const path = require('path')
const fs = require('fs');
const glob = require('glob')
const webpack = require('webpack')

// webpack plugins
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CompressionPlugin = require("compression-webpack-plugin")
const GenSourceCode = require('./webpack.gensrc')
const WebpackI18nPlugin = require("./webpack.i18n");

const date = new Date()
const DEV_MODE = process.env.NODE_ENV !== 'production' && process.argv.indexOf('-p') === -1,
    BUILD_NUMBER = `${date.getYear()}${date.getMonth()}${date.getDay()}.${Math.ceil((date-new Date().setHours(0,0,0,0))/8641)}`

/*---------------------------------------------------
 Define which directories are included from the build based on the config file
 ---------------------------------------------------*/

const EXCLUDE_FROM_BUILD = [
    path.resolve(__dirname, 'node_modules'),
    path.resolve(__dirname, 'test'),
    path.resolve(__dirname, 'server'),
    path.resolve(__dirname, 'build'),
    path.resolve(__dirname, 'extensions'),
    path.resolve(__dirname, 'client/components/ui'),
    path.resolve(__dirname, './api')]

const INCLUDE_IN_BUILD = []

const APP_CONFIG = require('./buildconfig.json')
const PACKAGE_JSON = require('./package.json')

const APP_VALUES = {
    DEV_MODE,
    BUILD_NUMBER,
    APP_NAME: PACKAGE_JSON.name,
    APP_VERSION: PACKAGE_JSON.version,
    APP_DESCRIPTION: PACKAGE_JSON.description,
    APP_COLOR: '#2196f3'
}

if (APP_CONFIG.extensions) {
    for (const extensionName in APP_CONFIG.extensions) {
        if (APP_CONFIG.extensions[extensionName].active) {
            INCLUDE_IN_BUILD.push(path.resolve(__dirname, 'extensions/' + extensionName))
        }
    }
}

if (APP_CONFIG.ui) {
    APP_CONFIG.ui.forEach(ui => {
        INCLUDE_IN_BUILD.push(path.resolve(__dirname, 'client/components/ui/impl/' + ui.impl))
    })
}

const excludeFunction = (path) => {

    for (let i = 0; i < EXCLUDE_FROM_BUILD.length; i++) {
        if (path.indexOf(EXCLUDE_FROM_BUILD[i]) === 0) {
            // it belongs to the excluded files

            for (let j = 0; j < INCLUDE_IN_BUILD.length; j++) {
                if (path.indexOf(INCLUDE_IN_BUILD[j]) === 0) {
                    // it is an exception and should be included anyway
                    return false
                }
            }

            return true
        }
    }
    return false
}

const replacePlaceholders = (content, path) => {

    const result = new Function('const {' + Object.keys(APP_VALUES).join(',') + '} = this.APP_VALUES;return `' + content + '`').call({APP_VALUES})
    return result
}

const config = {
    entry: './client/index.js',
    target: 'web',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].bundle.js?v=' + BUILD_NUMBER,
        chunkFilename: '[name].bundle.js?v=' + BUILD_NUMBER,
        publicPath: '/'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: excludeFunction,
                loader: 'babel-loader'
            },
            {
                test: /\.global\.css$/,
                exclude: excludeFunction,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader"
                ]
            },
            {
                test: /^(?:(?!\.global).)*\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.global\.less$/,
                exclude: excludeFunction,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "less-loader"
                ]
            },
            {
                test: /^(?:(?!\.global).)*\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            }
        ]
    },
    plugins: [
        new GenSourceCode(APP_VALUES), /* Generate some source code based on the buildconfig.json file */
        new MiniCssExtractPlugin({
            filename: 'style.css',
            allChunks: true
        }), /* Extract css from bundle */
        new WebpackI18nPlugin({
            src: './**/*.tr.json',
            dest: '[name].js'
        })
    ],
    optimization: {
        minimizer: []
    }
}

/**
 *  Developer / Debug Config
 */
if (DEV_MODE) {
    console.log('Build for developing')
    config.mode = 'development'

    const PORT = (process.env.PORT || 8080)
    const API_PORT = (process.env.API_PORT || 3000)

    config.devServer = {
        historyApiFallback: true,
        inline: true,
        hot: true,
        port: PORT,
        host: '0.0.0.0',
        proxy: {
            '/graphql': {target: `http://0.0.0.0:${API_PORT}`},
            '/ws': {
                target: `ws://localhost:${API_PORT}`,
                ws: true
            }
        }
    }

    /* For Debugging porpuses */
    config.devtool = 'eval'

    config.plugins.push(new webpack.HotModuleReplacementPlugin())

} else {
    console.log('Build for production')
    config.mode = 'production'

    const CopyWebpackPlugin = require('copy-webpack-plugin')
    config.plugins.push(
        new CopyWebpackPlugin([
            {
                from: 'index.html', to: 'index.html',
                transform: replacePlaceholders
            },
            {
                from: 'serviceworker.js', to: 'serviceworker.js',
                transform: replacePlaceholders
            },
            {
                from: 'manifest.json', to: 'manifest.json',
                transform: replacePlaceholders
            },
            {from: 'favicon.ico', to: 'favicon.ico'},
            {from: 'favicon.svg', to: 'favicon.svg'},
            {from: 'favicon-192x192.png', to: 'favicon-192x192.png'},
            {from: 'favicon-512x512.png', to: 'favicon-512x512.png'}
        ])
    )

    config.plugins.push(
        new CompressionPlugin({
            minRatio: 0.95
        })
    )

    config.optimization.minimizer.push(
        new UglifyJSPlugin({
            uglifyOptions: {
                compress: {
                    drop_console: true
                },
                output: {
                    comments: false,
                    semicolons: true,
                    shebang: true,
                    beautify: false
                }
            }
        }))

    /*const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
     config.plugins.push(new BundleAnalyzerPlugin())*/

    //config.devtool = 'source-map'
}

module.exports = config

/* --port 8080 --hot --host 0.0.0.0 --content-base . */<commit_msg>Small improvments<commit_after>const path = require('path')
const fs = require('fs');
const glob = require('glob')
const webpack = require('webpack')

// webpack plugins
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CompressionPlugin = require("compression-webpack-plugin")
const GenSourceCode = require('./webpack.gensrc')
const WebpackI18nPlugin = require("./webpack.i18n");

const date = new Date()
const DEV_MODE = process.env.NODE_ENV !== 'production' && process.argv.indexOf('-p') === -1,
    BUILD_NUMBER = `${date.getYear() - 100}${date.getMonth() + 1}${date.getDate()}.${Math.ceil((date - new Date().setHours(0, 0, 0, 0)) / 8641)}`

/*---------------------------------------------------
 Define which directories are included from the build based on the config file
 ---------------------------------------------------*/

const EXCLUDE_FROM_BUILD = [
    path.resolve(__dirname, 'node_modules'),
    path.resolve(__dirname, 'test'),
    path.resolve(__dirname, 'server'),
    path.resolve(__dirname, 'build'),
    path.resolve(__dirname, 'extensions'),
    path.resolve(__dirname, 'client/components/ui'),
    path.resolve(__dirname, './api')]

const INCLUDE_IN_BUILD = []

const APP_CONFIG = require('./buildconfig.json')
const PACKAGE_JSON = require('./package.json')

const APP_VALUES = {
    DEV_MODE,
    BUILD_NUMBER,
    APP_NAME: PACKAGE_JSON.name,
    APP_VERSION: PACKAGE_JSON.version,
    APP_DESCRIPTION: PACKAGE_JSON.description,
    APP_COLOR: '#2196f3'
}

if (APP_CONFIG.extensions) {
    for (const extensionName in APP_CONFIG.extensions) {
        if (APP_CONFIG.extensions[extensionName].active) {
            INCLUDE_IN_BUILD.push(path.resolve(__dirname, 'extensions/' + extensionName))
        }
    }
}

if (APP_CONFIG.ui) {
    APP_CONFIG.ui.forEach(ui => {
        INCLUDE_IN_BUILD.push(path.resolve(__dirname, 'client/components/ui/impl/' + ui.impl))
    })
}

const excludeFunction = (path) => {

    for (let i = 0; i < EXCLUDE_FROM_BUILD.length; i++) {
        if (path.indexOf(EXCLUDE_FROM_BUILD[i]) === 0) {
            // it belongs to the excluded files

            for (let j = 0; j < INCLUDE_IN_BUILD.length; j++) {
                if (path.indexOf(INCLUDE_IN_BUILD[j]) === 0) {
                    // it is an exception and should be included anyway
                    return false
                }
            }

            return true
        }
    }
    return false
}

const replacePlaceholders = (content, path) => {

    const result = new Function('const {' + Object.keys(APP_VALUES).join(',') + '} = this.APP_VALUES;return `' + content + '`').call({APP_VALUES})
    return result
}

const config = {
    entry: './client/index.js',
    target: 'web',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].bundle.js?v=' + BUILD_NUMBER,
        chunkFilename: '[name].bundle.js?v=' + BUILD_NUMBER,
        publicPath: '/'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: excludeFunction,
                loader: 'babel-loader'
            },
            {
                test: /\.global\.css$/,
                exclude: excludeFunction,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader"
                ]
            },
            {
                test: /^(?:(?!\.global).)*\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.global\.less$/,
                exclude: excludeFunction,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "less-loader"
                ]
            },
            {
                test: /^(?:(?!\.global).)*\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            }
        ]
    },
    plugins: [
        new GenSourceCode(APP_VALUES), /* Generate some source code based on the buildconfig.json file */
        new MiniCssExtractPlugin({
            filename: 'style.css',
            allChunks: true
        }), /* Extract css from bundle */
        new WebpackI18nPlugin({
            src: './**/*.tr.json',
            dest: '[name].js'
        })
    ],
    optimization: {
        minimizer: []
    }
}

/**
 *  Developer / Debug Config
 */
if (DEV_MODE) {
    console.log('Build for developing')
    config.mode = 'development'

    const PORT = (process.env.PORT || 8080)
    const API_PORT = (process.env.API_PORT || 3000)

    config.devServer = {
        historyApiFallback: true,
        inline: true,
        hot: true,
        port: PORT,
        host: '0.0.0.0',
        proxy: {
            '/graphql': {target: `http://0.0.0.0:${API_PORT}`},
            '/ws': {
                target: `ws://localhost:${API_PORT}`,
                ws: true
            }
        }
    }

    /* For Debugging porpuses */
    config.devtool = 'eval'

    config.plugins.push(new webpack.HotModuleReplacementPlugin())

} else {
    console.log('Build for production')
    config.mode = 'production'

    const CopyWebpackPlugin = require('copy-webpack-plugin')
    config.plugins.push(
        new CopyWebpackPlugin([
            {
                from: 'index.html', to: 'index.html',
                transform: replacePlaceholders
            },
            {
                from: 'serviceworker.js', to: 'serviceworker.js',
                transform: replacePlaceholders
            },
            {
                from: 'manifest.json', to: 'manifest.json',
                transform: replacePlaceholders
            },
            {from: 'favicon.ico', to: 'favicon.ico'},
            {from: 'favicon.svg', to: 'favicon.svg'},
            {from: 'favicon-192x192.png', to: 'favicon-192x192.png'},
            {from: 'favicon-512x512.png', to: 'favicon-512x512.png'}
        ])
    )

    config.plugins.push(
        new CompressionPlugin({
            minRatio: 0.95
        })
    )

    config.optimization.minimizer.push(
        new UglifyJSPlugin({
            uglifyOptions: {
                compress: {
                    drop_console: true
                },
                output: {
                    comments: false,
                    semicolons: true,
                    shebang: true,
                    beautify: false
                }
            }
        }))

    /*const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
     config.plugins.push(new BundleAnalyzerPlugin())*/

    //config.devtool = 'source-map'
}

module.exports = config

/* --port 8080 --hot --host 0.0.0.0 --content-base . */<|endoftext|>


<commit_before>
siggy2.Activity = siggy2.Activity || {};

siggy2.Activity.Thera = function(core)
{
	this.key = 'thera';
	this._updateTimeout = null;
	this.core = core;
	this.sigClocks = {};
	this.eolClocks = {};

	this.templateRow = Handlebars.compile( $("#template-thera-table-row").html() );

	this.table = $('#thera-exits-table tbody');

	var tableSorterHeaders = {
		0: {
			sortInitialOrder: 'asc'
		},
	};

	$('#thera-exits-table').tablesorter(
	{
		headers: tableSorterHeaders
	});
	$('#thera-exits-table').trigger("sorton", [ [[0,0]] ]);

}

siggy2.Activity.Thera.prototype.start = function()
{
	$('#activity-' + this.key).show();
	this.update();
}

siggy2.Activity.Thera.prototype.stop = function()
{
	clearTimeout(this._updateTimeout);
	$('#activity-' + this.key).hide();
}

siggy2.Activity.Thera.prototype.update = function()
{
	var $this = this;
	$.ajax({
				url: this.core.settings.baseUrl + 'thera/latest_exits',
				dataType: 'json',
				cache: false,
				async: true,
				method: 'get',
				success: function (data)
				{
					$this.updateTable(data);

					$this._updateTimeout = setTimeout(function(thisObj)
					{
						thisObj.update()
					}, 10000, $this);
				}
		});
}

siggy2.Activity.Thera.prototype.updateTable = function( exits )
{
	var $this = this;

	$('#thera-exits-table tbody tr').each(function()
	{
		var id = $(this).data('id');

		if( typeof exits[id] == 'undefined' )
		{
			$(this).children('td.wormhole-type').qtip('destroy');

			if( typeof $this.sigClocks[id] != 'undefined' )
			{
				$this.sigClocks[i].destroy();
				delete $this.sigClocks[i];
			}

			if( typeof $this.eolClocks[id] != 'undefined' )
			{
				$this.eolClocks[i].destroy();
				delete $this.eolClocks[i];
			}

			$(this).remove();
		}
		else
		{
			exits[id].row_already_exists = true;
		}
	});

	for( var i in exits )
	{
		var exit = exits[i];
		if( exit.row_already_exists )
			continue;

		var wh = siggy2.StaticData.getWormholeByID(exit.wormhole_type);

		if( wh != null )
		{
			desc_tooltip = siggy2.StaticData.templateWormholeInfoTooltip(wh);
			exit.wormhole_name = wh.name;
		}

		var row = this.templateRow( exit );

		this.table.append(row);

		this.sigClocks[exit.id] = new siggy2.Timer(exit.created_at * 1000, null, '#thera-sig-' + exit.id + ' td.age span.age-clock', "test");

		if( wh != null )
		{
			var endDate = parseInt(exit.created_at)+(3600*wh.lifetime);
			this.eolClocks[exit.id] = new siggy2.Timer(exit.created_at * 1000, endDate* 1000, '#thera-sig-' + exit.id + ' td.age p.eol-clock', "test");
		}

		$('#thera-sig-' + exit.id + ' td.wormhole-type').qtip({
			content: {
				text: desc_tooltip
			},
			position: {
				target: 'mouse',
				adjust: { x: 5, y: 5 },
				viewport: $(window)
			}
		});
	}

	$('#thera-exits-table').trigger('update');
}
<commit_msg>Add copyright header<commit_after>/*
* @license Proprietary
* @copyright Copyright (c) 2014 borkedLabs - All Rights Reserved
*/

siggy2.Activity = siggy2.Activity || {};

siggy2.Activity.Thera = function(core)
{
	this.key = 'thera';
	this._updateTimeout = null;
	this.core = core;
	this.sigClocks = {};
	this.eolClocks = {};

	this.templateRow = Handlebars.compile( $("#template-thera-table-row").html() );

	this.table = $('#thera-exits-table tbody');

	var tableSorterHeaders = {
		0: {
			sortInitialOrder: 'asc'
		},
	};

	$('#thera-exits-table').tablesorter(
	{
		headers: tableSorterHeaders
	});

	$('#thera-exits-table').trigger("sorton", [ [[0,0]] ]);
}

siggy2.Activity.Thera.prototype.start = function()
{
	$('#activity-' + this.key).show();
	this.update();
}

siggy2.Activity.Thera.prototype.stop = function()
{
	clearTimeout(this._updateTimeout);
	$('#activity-' + this.key).hide();
}

siggy2.Activity.Thera.prototype.update = function()
{
	var $this = this;
	$.ajax({
				url: this.core.settings.baseUrl + 'thera/latest_exits',
				dataType: 'json',
				cache: false,
				async: true,
				method: 'get',
				success: function (data)
				{
					$this.updateTable(data);

					$this._updateTimeout = setTimeout(function(thisObj)
					{
						thisObj.update()
					}, 10000, $this);
				}
		});
}

siggy2.Activity.Thera.prototype.updateTable = function( exits )
{
	var $this = this;

	$('#thera-exits-table tbody tr').each(function()
	{
		var id = $(this).data('id');

		if( typeof exits[id] == 'undefined' )
		{
			$(this).children('td.wormhole-type').qtip('destroy');

			if( typeof $this.sigClocks[id] != 'undefined' )
			{
				$this.sigClocks[i].destroy();
				delete $this.sigClocks[i];
			}

			if( typeof $this.eolClocks[id] != 'undefined' )
			{
				$this.eolClocks[i].destroy();
				delete $this.eolClocks[i];
			}

			$(this).remove();
		}
		else
		{
			exits[id].row_already_exists = true;
		}
	});

	for( var i in exits )
	{
		var exit = exits[i];
		if( exit.row_already_exists )
			continue;

		var wh = siggy2.StaticData.getWormholeByID(exit.wormhole_type);

		if( wh != null )
		{
			desc_tooltip = siggy2.StaticData.templateWormholeInfoTooltip(wh);
			exit.wormhole_name = wh.name;
		}

		var row = this.templateRow( exit );

		this.table.append(row);

		this.sigClocks[exit.id] = new siggy2.Timer(exit.created_at * 1000, null, '#thera-sig-' + exit.id + ' td.age span.age-clock', "test");

		if( wh != null )
		{
			var endDate = parseInt(exit.created_at)+(3600*wh.lifetime);
			this.eolClocks[exit.id] = new siggy2.Timer(exit.created_at * 1000, endDate* 1000, '#thera-sig-' + exit.id + ' td.age p.eol-clock', "test");
		}

		$('#thera-sig-' + exit.id + ' td.wormhole-type').qtip({
			content: {
				text: desc_tooltip
			},
			position: {
				target: 'mouse',
				adjust: { x: 5, y: 5 },
				viewport: $(window)
			}
		});
	}

	$('#thera-exits-table').trigger('update');
}
<|endoftext|>


<commit_before>const path = require('path');

module.exports = {
  entry: [
    path.resolve('src', 'index.js')
  ],
  output: {
    path: path.resolve('dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            ['@babel/env', {
              'useBuiltIns': 'usage',
              'targets': {
                'node': 'current',
                'browsers': 'last 2 versions'
              }
            }]
          ]
        }
      }
    ]
  },
  resolve: {
    modules: [
      path.resolve('src'),
      'node_modules'
    ]
  },
  devtool: 'source-map',
  devServer: {
    port: 8000,
    open: true,
    contentBase: path.resolve('dist'),
    watchContentBase: true
  }
};
<commit_msg>Refactor<commit_after>const path = require('path');

module.exports = {
  entry: [
    path.resolve('src', 'index.js')
  ],
  output: {
    path: path.resolve('dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            ['@babel/preset-env', {
              useBuiltIns: 'usage',
              targets: {
                node: 'current',
                browsers: 'last 2 versions'
              }
            }]
          ]
        }
      }
    ]
  },
  resolve: {
    modules: [
      path.resolve('src'),
      'node_modules'
    ]
  },
  devtool: 'source-map',
  devServer: {
    port: 8000,
    open: true,
    contentBase: path.resolve('dist'),
    watchContentBase: true
  }
};
<|endoftext|>


<commit_before>/* jshint node:true */
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

const JS_BUNDLE_NAME = 'jsxc.bundle.js';

const extractSass = new ExtractTextPlugin({
   filename: 'styles/jsxc.bundle.css',
   allChunks: true,
});

const definePlugin = new webpack.DefinePlugin({
   __VERSION__: JSON.stringify(require("./package.json").version),
   __BUILD_DATE__: JSON.stringify((new Date()).toDateString()),
   __BUNDLE_NAME__: JS_BUNDLE_NAME,
});

const fileLoader = {
   loader: 'file-loader',
   options: {
      name: '[path][name]-[sha1:hash:hex:8].[ext]',
      outputPath: 'assets/'
   }
};

module.exports = {
   entry: ['./scss/main.scss', './src/index.ts'],
   output: {
      filename: JS_BUNDLE_NAME,
      path: path.resolve(__dirname, './dist/'),
      publicPath: 'dist/',
      libraryTarget: 'var',
      library: 'jsxc'
   },
   node: {
      fs: 'empty'
   },
   module: {
      rules: [{
            test: /\.ts$/,
            loader: 'ts-loader',
            exclude: /node_modules/,
         },
         {
            test: /\.hbs$/,
            loader: 'handlebars-loader',
            exclude: /node_modules/,
            query: {
               helperDirs: [
                  path.resolve(__dirname, "template", 'helpers')
               ],
               ignorePartials: ['list']
            }
         },
         {
            test: /\.css$/,
            use: extractSass.extract({
               use: 'css-loader?importLoaders=1',
            }),
         },
         {
            test: /\.(sass|scss)$/,
            use: extractSass.extract({
               use: [{
                  loader: 'css-loader',
                  options: {
                     url: false
                  }
               }, 'sass-loader']
            })
         },
         {
            test: /.*\.(png|jpg|gif|mp3|wav)$/,
            use: [fileLoader]
         },
         {
            test: /.*\.(js)$/,
            resourceQuery: /path/,
            use: [fileLoader]
         }
      ]
   },
   resolve: {
      extensions: [".ts", ".js", ".hbs"]
   },
   externals: {
      'jquery': 'jQuery',
      'child_process': 'child_process',
      'webworker-threads': 'webworker-threads'
   },
   plugins: [
      extractSass,
      definePlugin,
      new CleanWebpackPlugin(['dist']),
      new CopyWebpackPlugin([{
         from: 'images/',
         to: 'images/'
      }, {
         from: 'node_modules/emojione/assets/svg/',
         to: 'images/emojione/'
      }]),
      new webpack.LoaderOptionsPlugin({
            options: {
                  handlebarsLoader: {}
            }
      })
   ],
   devServer: {
      port: 8091,
      inline: true,
      open: true,
      openPage: 'example/ts.html',
      proxy: {
            "/http-bind": "http://localhost:5280"
      },
      watchOptions: {
            aggregateTimeout: 1300,
            ignored: "/dist/"
      }
    },
};
<commit_msg>fix handlebars options<commit_after>/* jshint node:true */
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

const JS_BUNDLE_NAME = 'jsxc.bundle.js';

const extractSass = new ExtractTextPlugin({
   filename: 'styles/jsxc.bundle.css',
   allChunks: true,
});

const definePlugin = new webpack.DefinePlugin({
   __VERSION__: JSON.stringify(require("./package.json").version),
   __BUILD_DATE__: JSON.stringify((new Date()).toDateString()),
   __BUNDLE_NAME__: JS_BUNDLE_NAME,
});

const fileLoader = {
   loader: 'file-loader',
   options: {
      name: '[path][name]-[sha1:hash:hex:8].[ext]',
      outputPath: 'assets/'
   }
};

module.exports = {
   entry: ['./scss/main.scss', './src/index.ts'],
   output: {
      filename: JS_BUNDLE_NAME,
      path: path.resolve(__dirname, './dist/'),
      publicPath: 'dist/',
      libraryTarget: 'var',
      library: 'jsxc'
   },
   node: {
      fs: 'empty'
   },
   module: {
      rules: [{
            test: /\.ts$/,
            loader: 'ts-loader',
            exclude: /node_modules/,
         },
         {
            test: /\.hbs$/,
            loader: 'handlebars-loader',
            exclude: /node_modules/,
            options: {
               helperDirs: [
                  path.resolve(__dirname, 'template', 'helpers')
               ],
               partialDirs: [
                  path.resolve(__dirname, 'template', 'partials')
               ]
            }
         },
         {
            test: /\.css$/,
            use: extractSass.extract({
               use: 'css-loader?importLoaders=1',
            }),
         },
         {
            test: /\.(sass|scss)$/,
            use: extractSass.extract({
               use: [{
                  loader: 'css-loader',
                  options: {
                     url: false
                  }
               }, 'sass-loader']
            })
         },
         {
            test: /.*\.(png|jpg|gif|mp3|wav)$/,
            use: [fileLoader]
         },
         {
            test: /.*\.(js)$/,
            resourceQuery: /path/,
            use: [fileLoader]
         }
      ]
   },
   resolve: {
      extensions: [".ts", ".js", ".hbs"]
   },
   externals: {
      'jquery': 'jQuery',
      'child_process': 'child_process',
      'webworker-threads': 'webworker-threads'
   },
   plugins: [
      extractSass,
      definePlugin,
      new CleanWebpackPlugin(['dist']),
      new CopyWebpackPlugin([{
         from: 'images/',
         to: 'images/'
      }, {
         from: 'node_modules/emojione/assets/svg/',
         to: 'images/emojione/'
      }]),
      new webpack.LoaderOptionsPlugin({
            options: {
                  handlebarsLoader: {}
            }
      })
   ],
   devServer: {
      port: 8091,
      inline: true,
      open: true,
      openPage: 'example/ts.html',
      proxy: {
            "/http-bind": "http://localhost:5280"
      },
      watchOptions: {
            aggregateTimeout: 1300,
            ignored: "/dist/"
      }
    },
};
<|endoftext|>


<commit_before>/**
 * Javascript for the Content manager
 *
 * @author Dean Blackborough <dean@g3d-development.com>
 * @copyright G3D Development Limited
 * @license https://github.com/Dlayer/dlayer/blob/master/LICENSE
 */
var contentManager =
{
	pageBackgroundColor: null,
	highlightColor: '#e1dc50',
	clickColor: '#c3be50',

	/**
	 * Add the hover event for the content page and the click event to store session value
	 */
	pageSelector: function()
	{
		var selector = 'div.container-fluid.selectable';

		$(selector).hover(
			function()
			{
				contentManager.pageBackgroundColor = $(this).css('background-color');
				$(this).css('background-color', contentManager.highlightColor);
				$(this).css('cursor', 'pointer');
			},
			function ()
			{
				$(this).css('background-color', contentManager.pageBackgroundColor);
			}
		);
		$(selector).click(
			function(e)
			{
				e.preventDefault();

				$(this).css('background-color', contentManager.clickColor);

				window.location.replace('/content/design/set-page-selected');
			}
		);
	},

	/**
	 * Selector for rows, adds a hover event to change the background colour and then a click event to allow the
	 * row to be selected
	 */
	rowSelector: function()
	{
		var selector = 'div.selected > div.row.selectable';
		var background_color = null;

		$(selector).hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', contentManager.highlightColor);
				$(this).css('cursor', 'pointer');
				$(this).find('div.row-mover').show();
			},
			function() {
				$(this).css('background-color', background_color);
				$(this).find('div.row-mover').hide();
			}
		);
		$(selector).click(
			function() {
				$(this).css('background-color', contentManager.clickColor);
				window.location.replace('/content/design/set-selected-row/id/' + $(this).data('row-id'));
			}
		);
	},

	/**
	 * Selector for columns, adds a hover event to change the background colour and then a click event to allow the
	 * column to be selected
	 */
	columnSelector: function()
	{
		var selector = '.row.selected > .column.selectable';
		var background_color = null;

		$(selector).hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', contentManager.highlightColor);
				$(this).css('cursor', 'pointer');
				$(this).find('div.column-mover').show();
			},
			function() {
				$(this).css('background-color', background_color);
				$(this).find('div.column-mover').hide();
			}
		);
		$(selector).click(
			function() {
				$(this).css('background-color', contentManager.clickColor);
				window.location.replace('/content/design/set-selected-column/id/' + $(this).data('column-id'));
			}
		);
	},

	/**
	 * Selector for content items, adds a hover event to change the background colour and then a click even to allow the
	 * content item to be selected for editing
	 */
	contentSelector: function()
	{
		var selector = '.column.selected > .content.selectable';
		var background_color = null;

		$(selector).hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', contentManager.highlightColor);
				$(this).css('cursor', 'pointer');
				$('.content-mover-' + $(this).data('content-id')).show();
			},
			function() {
				$(this).css('background-color', background_color);
				$('.content-mover-' + $(this).data('content-id')).hide();
			}
		);
		$(selector).click(
			function() {
				$(this).css('background-color', contentManager.clickColor);

				window.location.replace('/content/design/set-selected-content/id/' +
					$(this).data('content-id') + '/tool/' + $(this).data('tool') + '/content-type/' +
					$(this).data('content-type'));
			}
		);
	},

	/**
	 * Row movement controls, show when a row has the selectable class applied
	 *
	 * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
	 */
	rowMover: function()
	{
		var selector = '.selected div.row.selectable';

		$(selector).each(
			function(index)
			{
				var id = $(this).data('row-id');

				if(index !== 0) {
					$(this).prepend(contentManager.moverButton('row-mover', 'up', 'Display sooner', id));
				}
				if(index !== ($(selector).length - 1)) {
					$(this).append(contentManager.moverButton('row-mover', 'down', 'Display later', id));
				}
			}
		);

		$(".row-mover").click(
			function(e) {
				e.stopPropagation();
				window.location.replace('/content/design/move-row/direction/' + $(this).data('move') +
					'/id/' + $(this).data('id'));
			}
		);
	},

	/**
	 * Column movement controls, show when a column has the selectable class applied
	 *
	 * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
	 */
	columnMover: function()
	{
		var selector = '.selected div.column.selectable';

		$(selector).each(
			function(index)
			{
				var id = $(this).data('column-id');

				if(index !== 0) {
					$(this).prepend(contentManager.moverButton('column-mover', 'up', 'Display sooner', id));
				}
				if(index !== ($(selector).length - 1)) {
					$(this).append(contentManager.moverButton('column-mover', 'down', 'Display later', id));
				}
			}
		);

		$(".column-mover").click(
			function(e) {
				e.stopPropagation();
				window.location.replace('/content/design/move-column/direction/' + $(this).data('move') +
					'/id/' + $(this).data('id'));
			}
		);
	},

	/**
	 * Content item movement controls, shows when a content items has the selectable class applied to it
	 *
	 * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
	 */
	contentMover: function()
	{
		var selector = 'div.column.selected .content.selectable';

		$(selector).each(
			function(index)
			{
				var id = $(this).data('content-id');

				if(index !== 0) {
					$(this).prepend(contentManager.moverButton('content-mover', 'up', 'Display sooner', id));

				}
				if(index !== ($(selector).length - 1)) {
					$(this).append(contentManager.moverButton('content-mover', 'down', 'Display later', id));
				}
			}
		);

		$(".content-mover").click(
			function(e) {
				e.stopPropagation();
				window.location.replace('/content/design/move-content/direction/' + $(this).data('move') +
					'/id/' + $(this).data('id'));
			}
		);
	},

	/**
	 * Generate the html for the movement controls
	 *
	 * @param moverClass Class for div
	 * @param direction Direction of movement
	 * @param text Text for button
	 * @param id Id of the item being moved
	 * @return {string}
	 */
	moverButton: function(moverClass, direction, text, id)
	{
		return '
' + text + '
';
	}
};
<commit_msg>Column colour<commit_after>/**
 * Javascript for the Content manager
 *
 * @author Dean Blackborough <dean@g3d-development.com>
 * @copyright G3D Development Limited
 * @license https://github.com/Dlayer/dlayer/blob/master/LICENSE
 */
var contentManager =
{
    pageBackgroundColor: null,
    highlightColor: '#e1dc50',
    clickColor: '#c3be50',

    /**
     * Add the hover event for the content page and the click event to store session value
     */
    pageSelector: function ()
    {
        var selector = 'div.container-fluid.selectable';

        $(selector).hover(
            function ()
            {
                contentManager.pageBackgroundColor = $(this).css('background-color');
                $(this).css('background-color', contentManager.highlightColor);
                $(this).css('cursor', 'pointer');
            },
            function ()
            {
                $(this).css('background-color', contentManager.pageBackgroundColor);
            }
        );
        $(selector).click(
            function (e)
            {
                e.preventDefault();

                $(this).css('background-color', contentManager.clickColor);

                window.location.replace('/content/design/set-page-selected');
            }
        );
    },

    /**
     * Selector for rows, adds a hover event to change the background colour and then a click event to allow the
     * row to be selected
     */
    rowSelector: function ()
    {
        var selector = 'div.selected > div.row.selectable';
        var selector_columns = 'div.selected > div.row.selectable div.column';
        var background_color = null;
        var background_colors_columns = [];

        $(selector).hover(
            function ()
            {
                background_color = $(this).css('background-color');

                var selector_columns = '.row[data-row-id="' + $(this).data('row-id') + '"] div.column';

                $(selector_columns).each(
                    function (index)
                    {
                        var id = $(this).data('column-id');
                        background_colors_columns[id] = $(this).css('background-color');
                        $('.column[data-column-id="' + id + '"]').css('background-color', 'transparent');
                    }
                );

                $(this).css('background-color', contentManager.highlightColor);
                $(this).css('cursor', 'pointer');
                $(this).find('div.row-mover').show();
            },
            function ()
            {
                var selector_columns = '.row[data-row-id="' + $(this).data('row-id') + '"] div.column';

                $(selector_columns).each(
                    function (index)
                    {
                        var id = $(this).data('column-id');
                        $('.column[data-column-id="' + id + '"]').css('background-color',
                            background_colors_columns[id]);
                    }
                );

                $(this).css('background-color', background_color);
                $(this).find('div.row-mover').hide();
            }
        );
        $(selector).click(
            function ()
            {
                $(this).css('background-color', contentManager.clickColor);
                window.location.replace('/content/design/set-selected-row/id/' + $(this).data('row-id'));
            }
        );
    },

    /**
     * Selector for columns, adds a hover event to change the background colour and then a click event to allow the
     * column to be selected
     */
    columnSelector: function ()
    {
        var selector = '.row.selected > .column.selectable';
        var background_color = null;

        $(selector).hover(
            function ()
            {
                background_color = $(this).css('background-color');
                $(this).css('background-color', contentManager.highlightColor);
                $(this).css('cursor', 'pointer');
                $(this).find('div.column-mover').show();
            },
            function ()
            {
                $(this).css('background-color', background_color);
                $(this).find('div.column-mover').hide();
            }
        );
        $(selector).click(
            function ()
            {
                $(this).css('background-color', contentManager.clickColor);
                window.location.replace('/content/design/set-selected-column/id/' + $(this).data('column-id'));
            }
        );
    },

    /**
     * Selector for content items, adds a hover event to change the background colour and then a click even to allow the
     * content item to be selected for editing
     */
    contentSelector: function ()
    {
        var selector = '.column.selected > .content.selectable';
        var background_color = null;

        $(selector).hover(
            function ()
            {
                background_color = $(this).css('background-color');
                $(this).css('background-color', contentManager.highlightColor);
                $(this).css('cursor', 'pointer');
                $('.content-mover-' + $(this).data('content-id')).show();
            },
            function ()
            {
                $(this).css('background-color', background_color);
                $('.content-mover-' + $(this).data('content-id')).hide();
            }
        );
        $(selector).click(
            function ()
            {
                $(this).css('background-color', contentManager.clickColor);

                window.location.replace('/content/design/set-selected-content/id/' +
                    $(this).data('content-id') + '/tool/' + $(this).data('tool') + '/content-type/' +
                    $(this).data('content-type'));
            }
        );
    },

    /**
     * Row movement controls, show when a row has the selectable class applied
     *
     * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
     */
    rowMover: function ()
    {
        var selector = '.selected div.row.selectable';

        $(selector).each(
            function (index)
            {
                var id = $(this).data('row-id');

                if (index !== 0) {
                    $(this).prepend(contentManager.moverButton('row-mover', 'up', 'Display sooner', id));
                }
                if (index !== ($(selector).length - 1)) {
                    $(this).append(contentManager.moverButton('row-mover', 'down', 'Display later', id));
                }
            }
        );

        $(".row-mover").click(
            function (e)
            {
                e.stopPropagation();
                window.location.replace('/content/design/move-row/direction/' + $(this).data('move') +
                    '/id/' + $(this).data('id'));
            }
        );
    },

    /**
     * Column movement controls, show when a column has the selectable class applied
     *
     * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
     */
    columnMover: function ()
    {
        var selector = '.selected div.column.selectable';

        $(selector).each(
            function (index)
            {
                var id = $(this).data('column-id');

                if (index !== 0) {
                    $(this).prepend(contentManager.moverButton('column-mover', 'up', 'Display sooner', id));
                }
                if (index !== ($(selector).length - 1)) {
                    $(this).append(contentManager.moverButton('column-mover', 'down', 'Display later', id));
                }
            }
        );

        $(".column-mover").click(
            function (e)
            {
                e.stopPropagation();
                window.location.replace('/content/design/move-column/direction/' + $(this).data('move') +
                    '/id/' + $(this).data('id'));
            }
        );
    },

    /**
     * Content item movement controls, shows when a content items has the selectable class applied to it
     *
     * @todo UX is currently incorrect for controls, check #127871441 in Pivotal
     */
    contentMover: function ()
    {
        var selector = 'div.column.selected .content.selectable';

        $(selector).each(
            function (index)
            {
                var id = $(this).data('content-id');

                if (index !== 0) {
                    $(this).prepend(contentManager.moverButton('content-mover', 'up', 'Display sooner', id));

                }
                if (index !== ($(selector).length - 1)) {
                    $(this).append(contentManager.moverButton('content-mover', 'down', 'Display later', id));
                }
            }
        );

        $(".content-mover").click(
            function (e)
            {
                e.stopPropagation();
                window.location.replace('/content/design/move-content/direction/' + $(this).data('move') +
                    '/id/' + $(this).data('id'));
            }
        );
    },

    /**
     * Generate the html for the movement controls
     *
     * @param moverClass Class for div
     * @param direction Direction of movement
     * @param text Text for button
     * @param id Id of the item being moved
     * @return {string}
     */
    moverButton: function (moverClass, direction, text, id)
    {
        return '
' + text + '
';
    }
};
<|endoftext|>


<commit_before>"use strict";
var path = require("path");
var webpack = require("webpack");
//var Clean = require('clean-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var OUTPUT_PATH = path.join(__dirname, "/troposphere/assets");
var CONTEXT_PATH = path.join(__dirname, "/troposphere/static/js");

var plugins = [
    new ExtractTextPlugin("[name].css", { allChunks: true })
//    new Clean(['.'], OUTPUT_PATH)
];

if (process.env.NODE_ENV === "production") {
  plugins.push(
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
        "process.env.NODE_ENV": JSON.stringify("production")
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  );
}

module.exports = {
  entry: {
    app: "./main",
    analytics: "./analytics",
    public: "./public_site/main"
  },
  context: CONTEXT_PATH,
  output: {
    path: OUTPUT_PATH,
    publicPath: "/assets/",
    filename: "[name].js"
  },
  module: {
    loaders: [
      { test: /bootstrap-sass/, loader: "imports?jQuery=jquery" },
      { test: /modernizr-latest\.js/, loader: "imports?this=>window,html5=>window.html5!exports?window.Modernizr" },
      { test: /\.json$/, loader: 'json-loader', include: path.join(__dirname, 'node_modules/moment-timezone')},
      { test: /\.js$/, loader: "babel?cacheDirectory", exclude: /(node_modules|troposphere\/static\/js\/lib)/ },
      { test: /\.(scss|sass)$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader?browsers=last 2 versions!sass-loader") },
      { test: /\.woff$/ , loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2$/, loader: "url?limit=10000&mimetype=application/font-woff2" },
      { test: /\.ttf$/  , loader: "file?mimetype=application/vnd.ms-fontobject" },
      { test: /\.eot$/  , loader: "file?mimetype=application/x-font-ttf" },
      { test: /\.svg$/  , loader: "file?mimetype=image/svg+xml" },
      { test: /\.(jpe?g|png|gif|ico)$/, loader: "file?name=images/[name].[ext]" }
    ]
  },

  plugins: plugins,
  resolve: {
    alias: {
      bootstrap: "bootstrap-sass",
      css: path.join(__dirname, "/troposphere/static/css/"),
      images: path.join(__dirname, "/troposphere/static/images/"),
      highcharts: "highcharts-commonjs"
    },
    root: [
      CONTEXT_PATH,
    ],
    extensions: ["", ".js", ".scss", ".sass"]
  }
};
<commit_msg>Use os.tmpdir for caching babel-loader files<commit_after>"use strict";
var path = require("path");
var webpack = require("webpack");
//var Clean = require('clean-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var OUTPUT_PATH = path.join(__dirname, "/troposphere/assets");
var CONTEXT_PATH = path.join(__dirname, "/troposphere/static/js");

var plugins = [
    new ExtractTextPlugin("[name].css", { allChunks: true })
//    new Clean(['.'], OUTPUT_PATH)
];

if (process.env.NODE_ENV === "production") {
  plugins.push(
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
        "process.env.NODE_ENV": JSON.stringify("production")
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  );
}

module.exports = {
  entry: {
    app: "./main",
    analytics: "./analytics",
    public: "./public_site/main"
  },
  context: CONTEXT_PATH,
  output: {
    path: OUTPUT_PATH,
    publicPath: "/assets/",
    filename: "[name].js"
  },
  module: {
    loaders: [
      { test: /bootstrap-sass/, loader: "imports?jQuery=jquery" },
      { test: /modernizr-latest\.js/, loader: "imports?this=>window,html5=>window.html5!exports?window.Modernizr" },
      { test: /\.json$/, loader: 'json-loader', include: path.join(__dirname, 'node_modules/moment-timezone')},
      { test: /\.js$/,
        loader: "babel",
        query: { cacheDirectory: '/tmp/' },
        exclude: /(node_modules|troposphere\/static\/js\/lib)/ },
      { test: /\.(scss|sass)$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader?browsers=last 2 versions!sass-loader") },
      { test: /\.woff$/ , loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2$/, loader: "url?limit=10000&mimetype=application/font-woff2" },
      { test: /\.ttf$/  , loader: "file?mimetype=application/vnd.ms-fontobject" },
      { test: /\.eot$/  , loader: "file?mimetype=application/x-font-ttf" },
      { test: /\.svg$/  , loader: "file?mimetype=image/svg+xml" },
      { test: /\.(jpe?g|png|gif|ico)$/, loader: "file?name=images/[name].[ext]" }
    ]
  },

  plugins: plugins,
  resolve: {
    alias: {
      bootstrap: "bootstrap-sass",
      css: path.join(__dirname, "/troposphere/static/css/"),
      images: path.join(__dirname, "/troposphere/static/images/"),
      highcharts: "highcharts-commonjs"
    },
    root: [
      CONTEXT_PATH,
    ],
    extensions: ["", ".js", ".scss", ".sass"]
  }
};
<|endoftext|>


<commit_before>/**
 * Javascript for the Content manager
 *
 * @author Dean Blackborough <dean@g3d-development.com>
 * @copyright G3D Development Limited
 * @license https://github.com/Dlayer/dlayer/blob/master/LICENSE
 */
var contentManager =
{
	pageBackgroundColor: null,

	/**
	 * Add the hover event for the content page and the click event to store session value
	 *
	 * @returns {Void}
	 */
	pageSelector: function()
	{
		$('div.container-fluid.selectable').hover(
			function()
			{
				contentManager.pageBackgroundColor = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function ()
			{
				$(this).css('background-color', contentManager.pageBackgroundColor);
			}
		);
		$('div.container-fluid.selectable').click(
			function()
			{
				$(this).css('background-color','#c3be50');

				window.location.replace('/content/design/set-page-selected');
			}
		);
	},

	/**
	 * Selector for rows, adds a hover event to change the background colour and then a click event to allow the
	 * row to be selected
	 *
	 * @returns {Void}
	 */
	rowSelector: function()
	{
		var background_color = null;

		$('div.selected > div.row.selectable').hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function() {
				$(this).css('background-color', background_color);
			}
		);
		$('div.selected > div.row.selectable').click(
			function() {
				$(this).css('background-color', '#66a7ba');

				var id = this.id.replace('row-', '');

				window.location.replace('/content/design/set-selected-row/id/' + id);
			}
		);
	},

	/**
	 * Selector for columns, adds a hover event to change the background colour and then a click event to allow the
	 * column to be selected
	 *
	 * @returns {Void}
	 */
	columnSelector: function()
	{
		var background_color = null;

		$('.row.selected > .column.selectable').hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function() {
				$(this).css('background-color', background_color);
			}
		);
		$('.row.selected > .column.selectable').click(
			function() {
				$(this).css('background-color', '#66a7ba');

				var id = this.id.replace('column-', '');

				window.location.replace('/content/design/set-selected-column/id/' + id);
			}
		);
	},
}
<commit_msg>Duplication<commit_after>/**
 * Javascript for the Content manager
 *
 * @author Dean Blackborough <dean@g3d-development.com>
 * @copyright G3D Development Limited
 * @license https://github.com/Dlayer/dlayer/blob/master/LICENSE
 */
var contentManager =
{
	pageBackgroundColor: null,

	/**
	 * Add the hover event for the content page and the click event to store session value
	 *
	 * @returns {Void}
	 */
	pageSelector: function()
	{
		var selector = 'div.container-fluid.selectable';

		$(selector).hover(
			function()
			{
				contentManager.pageBackgroundColor = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function ()
			{
				$(this).css('background-color', contentManager.pageBackgroundColor);
			}
		);
		$(selector).click(
			function()
			{
				$(this).css('background-color','#c3be50');

				window.location.replace('/content/design/set-page-selected');
			}
		);
	},

	/**
	 * Selector for rows, adds a hover event to change the background colour and then a click event to allow the
	 * row to be selected
	 *
	 * @returns {Void}
	 */
	rowSelector: function()
	{
		var selector = 'div.selected > div.row.selectable';
		var background_color = null;

		$(selector).hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function() {
				$(this).css('background-color', background_color);
			}
		);
		$(selector).click(
			function() {
				$(this).css('background-color', '#66a7ba');

				var id = this.id.replace('row-', '');

				window.location.replace('/content/design/set-selected-row/id/' + id);
			}
		);
	},

	/**
	 * Selector for columns, adds a hover event to change the background colour and then a click event to allow the
	 * column to be selected
	 *
	 * @returns {Void}
	 */
	columnSelector: function()
	{
		var selector = '.row.selected > .column.selectable';
		var background_color = null;

		$(selector).hover(
			function() {
				background_color = $(this).css('background-color');
				$(this).css('background-color', '#e1dc50');
				$(this).css('cursor', 'pointer');
			},
			function() {
				$(this).css('background-color', background_color);
			}
		);
		$(selector).click(
			function() {
				$(this).css('background-color', '#66a7ba');

				var id = this.id.replace('column-', '');

				window.location.replace('/content/design/set-selected-column/id/' + id);
			}
		);
	},

	/**
	 * Selector for content items, adds a hover event to change the background colour and then a click even to allow the
	 * content item to be selected for editing
	 *
	 * @returns {Void}
	 */
	contentSelector: function()
	{
		var selector = '';
		var background_color = null;
	}
}
<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  // context: 'src',
  entry: [
    'webpack/hot/dev-server',
    'webpack-dev-server/client?http://localhost:8080',
    path.resolve('src/js/app')
  ],

  output: {
    path: path.resolve('build'),
    filename: 'bundle.js',
    publicPath: '/'
  },

  devServer: {
    contentBase: 'src',
    stats: {
      colors: true
    },
    quiet: true,
    hot: true
  },

  //loaders are webpack essential tool to bundle files
  module: {
    loaders: [
      //transpile es6 to es5
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      //parse .scss into css
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loader: ExtractTextPlugin.extract("style", "css!sass")
      },
      //bundle any files within limit of 10kb into bundle.js,
      //if more than limit it will be a separate network request
      {
        test: /\.(png|jpg)$/,
        exclude: /node_modules/,
        loader: 'url-loader?limit=10000&name=images/[name].[ext]'
      }, {
        test: /\.(eot|otf|ttf)$/,
        exclude: /node_modules/,
        loader: 'url-loader?limit=10000&name=fonts/[hash].[ext]'
      }
    ]
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new ExtractTextPlugin("css/styles.css"),
    new HtmlWebpackPlugin({
      minify: {
        removeComments: true,
        collapseWhitespace: true
      },
      template: './src/index.html',
      title: 'React Webpack',
    })
  ],

  //allow require without file extension
  resolve: {
    extensions: ['', '.js', '.es6']
  }
}
<commit_msg>Update build extension for es6<commit_after>var path = require('path');
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  // context: 'src',
  entry: [
    'webpack/hot/dev-server',
    'webpack-dev-server/client?http://localhost:8080',
    path.resolve('src/js/app')
  ],

  output: {
    path: path.resolve('build'),
    filename: 'bundle.js',
    publicPath: '/'
  },

  devServer: {
    contentBase: 'src',
    stats: {
      colors: true
    },
    quiet: true,
    hot: true
  },

  //loaders are webpack essential tool to bundle files
  module: {
    loaders: [
      //transpile es6 to es5
      {
        test: /\.(js|jsx|es6)$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      //parse .scss into css
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loader: ExtractTextPlugin.extract("style", "css!sass")
      },
      //bundle any files within limit of 10kb into bundle.js,
      //if more than limit it will be a separate network request
      {
        test: /\.(png|jpg)$/,
        exclude: /node_modules/,
        loader: 'url-loader?limit=10000&name=images/[name].[ext]'
      }, {
        test: /\.(eot|otf|ttf)$/,
        exclude: /node_modules/,
        loader: 'url-loader?limit=10000&name=fonts/[hash].[ext]'
      }
    ]
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new ExtractTextPlugin("css/styles.css"),
    new HtmlWebpackPlugin({
      minify: {
        removeComments: true,
        collapseWhitespace: true
      },
      template: './src/index.html',
      title: 'React Webpack',
    })
  ],

  //allow require without file extension
  resolve: {
    extensions: ['', '.js', '.es6', '.jsx']
  }
}
<|endoftext|>


<commit_before>/**
 * Movim Websocket
 *
 * This file define the websocket behaviour and handle its connection
 */

WebSocket.prototype.unregister = function() {
    this.send(JSON.stringify({'func' : 'unregister'}));
};

WebSocket.prototype.register = function(host) {
    this.send(JSON.stringify({'func' : 'register', 'host' : host}));
};

/**
 * Short function for MovimWebsocket.send
 */
function MWSs(widget, func, params) {
    MovimWebsocket.send(widget, func, params);
}

/**
 * @brief Definition of the MovimWebsocket object
 * @param string error
 */

var MovimWebsocket = {
    connection: null,
    attached: [], // Launched when the socket is connected to the daemon
    started: [], // Launched when the linker is started
    registered: [], // Launched when the linker is connected to XMPP
    attempts: 1,
    pong: false,
    closed: false,

    launchAttached : function() {
        // We hide the Websocket error
        document.getElementById('error_websocket').classList.add('hide');

        for(var i = 0; i < MovimWebsocket.attached.length; i++) {
            MovimWebsocket.attached[i]();
        }
    },

    launchRegistered : function() {
        for(var i = 0; i < MovimWebsocket.registered.length; i++) {
            MovimWebsocket.registered[i]();
        }
    },

    launchStarted : function() {
        for(var i = 0; i < MovimWebsocket.started.length; i++) {
            MovimWebsocket.started[i]();
        }
    },

    init : function() {
        if (SECURE_WEBSOCKET) {
            var uri = 'wss:' + BASE_URI + 'ws/';
        } else {
            var uri = 'ws:' + BASE_URI + 'ws/';
        }

        if (typeof this.connection === 'object') {
            this.connection.onclose = null;
            this.connection.close();
        }

        var date = new Date();

        this.connection = new WebSocket(uri +
            '?path=' + MovimUtils.urlParts().page +
            '&offset=' + date.getTimezoneOffset());

        this.connection.onopen = function(e) {
            console.log("Connection established!");
            MovimWebsocket.attempts = 1;
            MovimWebsocket.launchAttached();
            setTimeout(function() {
                MovimWebsocket.ping();
            }, 10000);
        };

        this.connection.onmessage = function(e) {
            var obj = JSON.parse(e.data);

            if (obj != null) {
                if (obj.func == 'registered') {
                    MovimWebsocket.launchRegistered();
                }

                if (obj.func == 'started') {
                    // If the linker was started but we're not on the login page
                    if (!['login', 'account', 'accountnext', 'tag', 'admin', 'about'].includes(MovimUtils.urlParts().page)) {
                        MovimUtils.disconnect();
                    } else {
                        MovimWebsocket.launchStarted();
                    }
                }

                if (obj.func == 'disconnected') {
                    MovimUtils.disconnect();
                }

                if (obj.func == 'pong') {
                    MovimWebsocket.pong = true;
                }

                MovimWebsocket.handle(obj);
            }
        };

        this.connection.onclose = function(e) {
            console.log("Connection closed by the server or session closed");

            if (e.code == 1008) {
                // The server closed the connection and asked to keep it this way
                this.closed = true;
                document.getElementById('error_websocket').classList.remove('hide');
                MovimWebsocket.connection.close();
            } if (e.code == 1006) {
                MovimWebsocket.reconnect();
            } else if (e.code == 1000) {
                MovimUtils.disconnect();
            }
        };

        this.connection.onerror = function(e) {
            console.log("Connection error!");

            // We show the Websocket error
            document.getElementById('error_websocket').classList.remove('hide');

            MovimWebsocket.reconnect();

            // We prevent the onclose launch
            this.onclose = null;
        };
    },

    send : function(widget, func, params) {
        if (this.connection.readyState == 1) {
            var body = {
                'w' : widget,
                'f' : func
            };

            if (params) body.p = params;

            this.connection.send(JSON.stringify(
                {'func' : 'message', 'b' : body}
            ));
        }
    },

    ajax : function(widget, func, params) {
        let xhr = new XMLHttpRequest;

        var body = {
            'w' : widget,
            'f' : func
        };

        if (params) body.p = params;

        xhr.open('POST', '?ajax');
        xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhr.send(JSON.stringify(
            {'func' : 'message', 'b' : body }
        ));

        return xhr;
    },

    // A ping/pong system to handle socket errors for buggy browser (Chrome on Linux…)
    ping : function() {
        if (this.connection.readyState == 1 && !this.closed) {
            this.connection.send(
                JSON.stringify(
                    {'func' : 'ping'}
                )
            );

            setTimeout(function() {
                if (MovimWebsocket.pong == false) {
                    MovimWebsocket.connection.onerror();
                } else {
                    MovimWebsocket.pong = false;
                    MovimWebsocket.ping();
                }
            }, 10000);
        }
    },

    attach : function(func) {
        if (typeof(func) === "function") {
            this.attached.push(func);
        }
    },

    register : function(func) {
        if (typeof(func) === "function") {
            this.registered.push(func);
        }
    },

    start : function(func) {
        if (typeof(func) === "function") {
            this.started.push(func);
        }
    },

    clearAttached : function() {
        this.attached = [];
    },

    handle : function(funcall) {
        if (funcall.func != null && (typeof window[funcall.func] == 'function')) {
            try {
                window[funcall.func].apply(null, funcall.params);
            } catch(err) {
                console.log("Error caught: "
                    + err.toString()
                    + " - "
                    + funcall.func
                    + ":"
                    + JSON.stringify(funcall.params)
                );
            }
        } else if (funcall.func != null) {
            var funcs  = funcall.func.split('.');
            var called = funcs[0];
            if (typeof window[called] == 'object'
            && typeof window[funcs[0]][funcs[1]] != 'undefined') {
                window[funcs[0]][funcs[1]].apply(null, funcall.params);
            }
        }
    },

    unregister : function(reload) {
        this.connection.unregister();
    },

    reconnect : function() {
        var interval = MovimWebsocket.generateInterval();
        console.log("Try to reconnect");
        setTimeout(function () {
            // We've tried to reconnect so increment the attempts by 1
            MovimWebsocket.attempts++;

            // Connection has closed so try to reconnect every 10 seconds.
            MovimWebsocket.init();
        }, interval);
    },

    generateInterval :function() {
        var maxInterval = (Math.pow(2, MovimWebsocket.attempts) - 1) * 1000;

        if (maxInterval > 30*1000) {
            maxInterval = 30*1000; // If the generated interval is more than 30 seconds, truncate it down to 30 seconds.
        }

        // generate the interval to a random number between 0 and the maxInterval determined from above
        return Math.random() * maxInterval;
    }
}

window.onbeforeunload = function() {
    MovimWebsocket.connection.onclose = function () {}; // disable onclose handler first
    MovimWebsocket.connection.close()
};

document.addEventListener("DOMContentLoaded", function(event) {
    // And we start it
    MovimWebsocket.init();
});

// If the Websocket was closed after some innactivity, we try to reconnect
window.addEventListener('focus', function() {
    if (typeof MovimWebsocket.connection === 'object'
     && MovimWebsocket.connection.readyState > 1) {
        MovimWebsocket.init();
    }
});<commit_msg>Proper fix<commit_after>/**
 * Movim Websocket
 *
 * This file define the websocket behaviour and handle its connection
 */

WebSocket.prototype.unregister = function() {
    this.send(JSON.stringify({'func' : 'unregister'}));
};

WebSocket.prototype.register = function(host) {
    this.send(JSON.stringify({'func' : 'register', 'host' : host}));
};

/**
 * Short function for MovimWebsocket.send
 */
function MWSs(widget, func, params) {
    MovimWebsocket.send(widget, func, params);
}

/**
 * @brief Definition of the MovimWebsocket object
 * @param string error
 */

var MovimWebsocket = {
    connection: null,
    attached: [], // Launched when the socket is connected to the daemon
    started: [], // Launched when the linker is started
    registered: [], // Launched when the linker is connected to XMPP
    attempts: 1,
    pong: false,
    closed: false,

    launchAttached : function() {
        // We hide the Websocket error
        document.getElementById('error_websocket').classList.add('hide');

        for(var i = 0; i < MovimWebsocket.attached.length; i++) {
            MovimWebsocket.attached[i]();
        }
    },

    launchRegistered : function() {
        for(var i = 0; i < MovimWebsocket.registered.length; i++) {
            MovimWebsocket.registered[i]();
        }
    },

    launchStarted : function() {
        for(var i = 0; i < MovimWebsocket.started.length; i++) {
            MovimWebsocket.started[i]();
        }
    },

    init : function() {
        if (SECURE_WEBSOCKET) {
            var uri = 'wss:' + BASE_URI + 'ws/';
        } else {
            var uri = 'ws:' + BASE_URI + 'ws/';
        }

        if (this.connection !== null) {
            this.connection.onclose = null;
            this.connection.close();
        }

        var date = new Date();

        this.connection = new WebSocket(uri +
            '?path=' + MovimUtils.urlParts().page +
            '&offset=' + date.getTimezoneOffset());

        this.connection.onopen = function(e) {
            console.log("Connection established!");
            MovimWebsocket.attempts = 1;
            MovimWebsocket.launchAttached();
            setTimeout(function() {
                MovimWebsocket.ping();
            }, 10000);
        };

        this.connection.onmessage = function(e) {
            var obj = JSON.parse(e.data);

            if (obj != null) {
                if (obj.func == 'registered') {
                    MovimWebsocket.launchRegistered();
                }

                if (obj.func == 'started') {
                    // If the linker was started but we're not on the login page
                    if (!['login', 'account', 'accountnext', 'tag', 'admin', 'about'].includes(MovimUtils.urlParts().page)) {
                        MovimUtils.disconnect();
                    } else {
                        MovimWebsocket.launchStarted();
                    }
                }

                if (obj.func == 'disconnected') {
                    MovimUtils.disconnect();
                }

                if (obj.func == 'pong') {
                    MovimWebsocket.pong = true;
                }

                MovimWebsocket.handle(obj);
            }
        };

        this.connection.onclose = function(e) {
            console.log("Connection closed by the server or session closed");

            if (e.code == 1008) {
                // The server closed the connection and asked to keep it this way
                this.closed = true;
                document.getElementById('error_websocket').classList.remove('hide');
                MovimWebsocket.connection.close();
            } if (e.code == 1006) {
                MovimWebsocket.reconnect();
            } else if (e.code == 1000) {
                MovimUtils.disconnect();
            }
        };

        this.connection.onerror = function(e) {
            console.log("Connection error!");

            // We show the Websocket error
            document.getElementById('error_websocket').classList.remove('hide');

            MovimWebsocket.reconnect();

            // We prevent the onclose launch
            this.onclose = null;
        };
    },

    send : function(widget, func, params) {
        if (this.connection.readyState == 1) {
            var body = {
                'w' : widget,
                'f' : func
            };

            if (params) body.p = params;

            this.connection.send(JSON.stringify(
                {'func' : 'message', 'b' : body}
            ));
        }
    },

    ajax : function(widget, func, params) {
        let xhr = new XMLHttpRequest;

        var body = {
            'w' : widget,
            'f' : func
        };

        if (params) body.p = params;

        xhr.open('POST', '?ajax');
        xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
        xhr.send(JSON.stringify(
            {'func' : 'message', 'b' : body }
        ));

        return xhr;
    },

    // A ping/pong system to handle socket errors for buggy browser (Chrome on Linux…)
    ping : function() {
        if (this.connection.readyState == 1 && !this.closed) {
            this.connection.send(
                JSON.stringify(
                    {'func' : 'ping'}
                )
            );

            setTimeout(function() {
                if (MovimWebsocket.pong == false) {
                    MovimWebsocket.connection.onerror();
                } else {
                    MovimWebsocket.pong = false;
                    MovimWebsocket.ping();
                }
            }, 10000);
        }
    },

    attach : function(func) {
        if (typeof(func) === "function") {
            this.attached.push(func);
        }
    },

    register : function(func) {
        if (typeof(func) === "function") {
            this.registered.push(func);
        }
    },

    start : function(func) {
        if (typeof(func) === "function") {
            this.started.push(func);
        }
    },

    clearAttached : function() {
        this.attached = [];
    },

    handle : function(funcall) {
        if (funcall.func != null && (typeof window[funcall.func] == 'function')) {
            try {
                window[funcall.func].apply(null, funcall.params);
            } catch(err) {
                console.log("Error caught: "
                    + err.toString()
                    + " - "
                    + funcall.func
                    + ":"
                    + JSON.stringify(funcall.params)
                );
            }
        } else if (funcall.func != null) {
            var funcs  = funcall.func.split('.');
            var called = funcs[0];
            if (typeof window[called] == 'object'
            && typeof window[funcs[0]][funcs[1]] != 'undefined') {
                window[funcs[0]][funcs[1]].apply(null, funcall.params);
            }
        }
    },

    unregister : function(reload) {
        this.connection.unregister();
    },

    reconnect : function() {
        var interval = MovimWebsocket.generateInterval();
        console.log("Try to reconnect");
        setTimeout(function () {
            // We've tried to reconnect so increment the attempts by 1
            MovimWebsocket.attempts++;

            // Connection has closed so try to reconnect every 10 seconds.
            MovimWebsocket.init();
        }, interval);
    },

    generateInterval :function() {
        var maxInterval = (Math.pow(2, MovimWebsocket.attempts) - 1) * 1000;

        if (maxInterval > 30*1000) {
            maxInterval = 30*1000; // If the generated interval is more than 30 seconds, truncate it down to 30 seconds.
        }

        // generate the interval to a random number between 0 and the maxInterval determined from above
        return Math.random() * maxInterval;
    }
}

window.onbeforeunload = function() {
    if (MovimWebsocket.connection !== null) {
        MovimWebsocket.connection.onclose = function () {}; // disable onclose handler first
        MovimWebsocket.connection.close()
    }
};

// If the Websocket was closed after some innactivity, we try to reconnect
window.addEventListener('focus', function() {
    if (MovimWebsocket.connection !== null
     && MovimWebsocket.connection.readyState > 1) {
        MovimWebsocket.init();
    }
});

document.addEventListener("DOMContentLoaded", function(event) {
    // And we start it
    MovimWebsocket.init();
});
<|endoftext|>


<commit_before>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const config = {
  context: path.resolve(__dirname, 'app'),
  entry: {
    app: './scripts/index.js'
  },
  output: {
    filename: '[hash].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: ['babel-loader', 'eslint-loader']
      },
      {
        test: /\.html$/,
        loaders: ['html-loader']
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loaders: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader?minimize=true', 'sass-loader']
        })
      },
      {
        test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
        loader: 'file-loader?name=./fonts/[name].[ext]'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({template: './index.html'}),
    new ExtractTextPlugin('[contenthash].css')
  ],
  //devtool: 'cheap-module-eval-source-map',
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};

module.exports = config;
<commit_msg>Split libs and app js code<commit_after>const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const config = {
  context: path.resolve(__dirname, 'app'),
  entry: {
    app: './scripts/index.js',
    lib: [
      'react',
      'react-dom',
      'prop-types',
      'react-router-dom',
      'react-redux',
      'redux',
      'redux-logger',
      'immutable'
    ]
  },
  output: {
    filename: '[name].[hash].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loaders: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader?minimize=true', 'sass-loader']
        })
      },
      {
        test: /\.woff2?$|\.ttf$|\.eot$|\.svg$/,
        loader: 'file-loader?name=./fonts/[name].[ext]'
      }
    ]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'lib',
      minChunks: Infinity
    }),
    new HtmlWebpackPlugin({template: './index.html'}),
    new ExtractTextPlugin('style.[contenthash].css')
  ],
  devtool: 'cheap-module-eval-source-map',
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};

module.exports = config;
<|endoftext|>