<commit_before>/**
 * @module decorator
 * @desc Basic decoration facilities.
 * @author Louis-Dominique Dubeau
 */
define(/** @lends module:decorator */ function (require, exports, module) {
'use strict';

var util = require("./util");
var $ = require("jquery");
var domutil = require("./domutil");
var jqutil = require("./jqutil");

function Decorator(domlistener, editor, gui_updater) {
    this._domlistener = domlistener;
    this._editor = editor;
    this._gui_updater = gui_updater;
}

exports.Decorator = Decorator;

Decorator.prototype.init = function ($root) {
    this._domlistener.addHandler(
        "added-element",
        "._real, ._phantom, ._phantom_wrap",
        this.contentEditableHandler.bind(this));

    var $contents = $root.contents();
    $root.empty();
    this._domlistener.startListening();
    this._gui_updater.insertAt($root.get(0), 0, $contents.toArray());
};

/**
 * This function adds a separator between each child element of the
 * element passed as el. The function only considers
 * _real elements.
 *
 */
Decorator.prototype.listDecorator = function (el, sep) {
    // We expect to work with a homogeneous list. That is, all
    // children the same element.
    var name_map = {};
    $(el).children('._real').each(function () {
        name_map[util.getOriginalName(this)] = 1;
    });

    var tags = Object.keys(name_map);
    if (tags.length > 1)
        throw new Error("calling listDecorator on a non-homogeneous list.");

    if (tags.length === 0)
        return; // Nothing to work with

    // First drop all children that are separators
    var me = this;
    $(el).children('[data-wed--separator-for]').each(function () {
        me._gui_updater.removeNode(this);
    });

    var tag_name = tags[0];

    // If sep is a string, create an appropriate div.
    if (typeof sep === "string")
        sep = $('
' + sep + "
");

    $(sep).addClass('_phantom');
    $(sep).attr('data-wed--separator-for', tag_name);

    var first = true;
    $(el).children('._real').each(function () {
        if (!first)
            me._gui_updater.insertBefore(this.parentNode, sep.clone().get(0),
                                         this);
        else
            first = false;
    });
};

Decorator.prototype.addRemListElementHandler = function (
    sep, $root, $parent, $previous_sibling, $next_sibling, $element) {
    this.listDecorator($parent, sep);
};

Decorator.prototype.includeListHandler = function (sep, $root, $element) {
    this.listDecorator($element, sep);
};

Decorator.prototype.contentEditableHandler = function (
    $root, $parent, $previous_sibling, $next_sibling, $element) {
    $element.findAndSelf('._phantom').attr("contenteditable", "false");
    $element.findAndSelf('._phantom_wrap').attr("contenteditable", "false");
    $element.findAndSelf('._real').attr("contenteditable", "true");
};

Decorator.prototype.elementDecorator = function (
    $root, el, pre_context_handler, post_context_handler) {
    var $el = $(el);
    el = $el.get(0);
    var orig_name = util.getOriginalName(el);
    // _[name]_label is used locally to make the function idempotent.
    var cls = "_" + orig_name + "_label";
    var me = this;
    $(el).children("." + util.escapeCSSClass(cls)).each(function () {
        me._gui_updater.removeNode(this);
    });
    var $pre = $(' ' + orig_name +
                 ' > ');
    this._gui_updater.insertNodeAt(el, 0, $pre.get(0));
    var $post = $(' < ' +
                  orig_name + ' ');
    this._gui_updater.insertBefore(el, $post.get(0), null);

    // Setup a handler so that clicking one label highlights it and
    // the other label.
    var data = {'$root': $root, '$pre': $pre, '$post': $post};
    $pre.click(data, this._elementButtonClickHandler.bind(this));
    $post.click(data, this._elementButtonClickHandler.bind(this));
    $pre.on("unclick", data, this._elementButtonUnclickHandler.bind(this));
    $post.on("unclick", data, this._elementButtonUnclickHandler.bind(this));

    if (pre_context_handler !== undefined)
        $pre.on('wed-context-menu', pre_context_handler);
    else
        $pre.on('wed-context-menu', false);

    if (post_context_handler !== undefined)
        $post.on('wed-context-menu', post_context_handler);
    else
        $post.on('wed-context-menu', false);
};

Decorator.prototype._elementButtonClickHandler = function (ev) {
    var data = ev.data;
    data.$pre.addClass("_button_clicked");
    data.$post.addClass("_button_clicked");
};

Decorator.prototype._elementButtonUnclickHandler = function (ev) {
    var data = ev.data;
    data.$pre.removeClass("_button_clicked");
    data.$post.removeClass("_button_clicked");
};

Decorator.prototype._contextMenuHandler = function (
    at_start, wed_ev, ev) {
    var node = $(wed_ev.currentTarget).parents('._real').first().get(0);
    var menu_items = [];
    var editor = this._editor;
    var mode = editor.mode;
    if (node.parentNode !== editor.gui_root) {
        // We first gather the transformations that pertain to the
        // node to which the label belongs.

        var orig = util.getOriginalName(node);
        var trs = mode.getContextualActions(
            ["unwrap", "delete-element"], orig, node, 0);
        if (trs !== undefined) {
            trs.forEach(function (tr) {
                var data = {node: node, element_name: orig };
                var $a = $("" +
                           tr.getDescriptionFor(data) + "");
                $a.click(data, tr.bound_handler);
                menu_items.push($("
").append($a).get(0));
            }.bind(this));
        }

        // Then we check what could be done before the node (if the
        // user clicked on an start element label) or after the node
        // (if the user clicked on an end element label).
        var parent = node.parentNode;
        var index = Array.prototype.indexOf.call(parent.childNodes, node);

        // If we're on the end label, we want the events *after* the node.
        if (!at_start)
            index++;

        var tree_caret = editor.toDataCaret(parent, index);
        var handler = function(e) {
            // We must do that here so that we can move the caret
            // without it being destroyed when the selection is popped
            // by dismissContextMenu.
            editor.dismissContextMenu();
            editor.setDataCaret(tree_caret);
            e.data.tr.bound_handler(e);
        }.bind(this);
        editor.validator.possibleAt(
            tree_caret[0], tree_caret[1]).forEach(function (ev) {
                if (ev.params[0] !== "enterStartTag")
                    return;

                var unresolved = editor.resolver.unresolveName(
                    ev.params[1], ev.params[2]);

                var trs = mode.getContextualActions(
                    "insert", unresolved, tree_caret[0], tree_caret[1]);
                if (trs === undefined)
                    return;

                for(var tr_ix = 0, tr; (tr = trs[tr_ix]) !== undefined;
                    ++tr_ix) {
                    var data = {tr: tr, element_name: unresolved };
                    var $a = $("" +
                               tr.getDescriptionFor(data) +
                               (at_start ? " before this element":
                                " after this element")
                               + "");
                    $a.click(data, handler);
                    menu_items.push($("

").append($a).get(0));
                }
            }.bind(this));

        // There's no menu to display, so let the event bubble up.
        if (menu_items === 0)
            return true;

        editor.displayContextMenu(ev.pageX, ev.pageY, menu_items);
        return false;
    }

    return true;
};

});
<commit_msg>$.empty() destroys data attached to an element.<commit_after>/**
 * @module decorator
 * @desc Basic decoration facilities.
 * @author Louis-Dominique Dubeau
 */
define(/** @lends module:decorator */ function (require, exports, module) {
'use strict';

var util = require("./util");
var $ = require("jquery");
var domutil = require("./domutil");
var jqutil = require("./jqutil");

function Decorator(domlistener, editor, gui_updater) {
    this._domlistener = domlistener;
    this._editor = editor;
    this._gui_updater = gui_updater;
}

exports.Decorator = Decorator;

Decorator.prototype.init = function ($root) {
    this._domlistener.addHandler(
        "added-element",
        "._real, ._phantom, ._phantom_wrap",
        this.contentEditableHandler.bind(this));

    var $contents = $root.contents();
    $contents.detach();
    this._domlistener.startListening();
    this._gui_updater.insertAt($root.get(0), 0, $contents.toArray());
};

/**
 * This function adds a separator between each child element of the
 * element passed as el. The function only considers
 * _real elements.
 *
 */
Decorator.prototype.listDecorator = function (el, sep) {
    // We expect to work with a homogeneous list. That is, all
    // children the same element.
    var name_map = {};
    $(el).children('._real').each(function () {
        name_map[util.getOriginalName(this)] = 1;
    });

    var tags = Object.keys(name_map);
    if (tags.length > 1)
        throw new Error("calling listDecorator on a non-homogeneous list.");

    if (tags.length === 0)
        return; // Nothing to work with

    // First drop all children that are separators
    var me = this;
    $(el).children('[data-wed--separator-for]').each(function () {
        me._gui_updater.removeNode(this);
    });

    var tag_name = tags[0];

    // If sep is a string, create an appropriate div.
    if (typeof sep === "string")
        sep = $('
' + sep + "
");

    $(sep).addClass('_phantom');
    $(sep).attr('data-wed--separator-for', tag_name);

    var first = true;
    $(el).children('._real').each(function () {
        if (!first)
            me._gui_updater.insertBefore(this.parentNode, sep.clone().get(0),
                                         this);
        else
            first = false;
    });
};

Decorator.prototype.addRemListElementHandler = function (
    sep, $root, $parent, $previous_sibling, $next_sibling, $element) {
    this.listDecorator($parent, sep);
};

Decorator.prototype.includeListHandler = function (sep, $root, $element) {
    this.listDecorator($element, sep);
};

Decorator.prototype.contentEditableHandler = function (
    $root, $parent, $previous_sibling, $next_sibling, $element) {
    $element.findAndSelf('._phantom').attr("contenteditable", "false");
    $element.findAndSelf('._phantom_wrap').attr("contenteditable", "false");
    $element.findAndSelf('._real').attr("contenteditable", "true");
};

Decorator.prototype.elementDecorator = function (
    $root, el, pre_context_handler, post_context_handler) {
    var $el = $(el);
    el = $el.get(0);
    var orig_name = util.getOriginalName(el);
    // _[name]_label is used locally to make the function idempotent.
    var cls = "_" + orig_name + "_label";
    var me = this;
    $(el).children("." + util.escapeCSSClass(cls)).each(function () {
        me._gui_updater.removeNode(this);
    });
    var $pre = $(' ' + orig_name +
                 ' > ');
    this._gui_updater.insertNodeAt(el, 0, $pre.get(0));
    var $post = $(' < ' +
                  orig_name + ' ');
    this._gui_updater.insertBefore(el, $post.get(0), null);

    // Setup a handler so that clicking one label highlights it and
    // the other label.
    var data = {'$root': $root, '$pre': $pre, '$post': $post};
    $pre.click(data, this._elementButtonClickHandler.bind(this));
    $post.click(data, this._elementButtonClickHandler.bind(this));
    $pre.on("unclick", data, this._elementButtonUnclickHandler.bind(this));
    $post.on("unclick", data, this._elementButtonUnclickHandler.bind(this));

    if (pre_context_handler !== undefined)
        $pre.on('wed-context-menu', pre_context_handler);
    else
        $pre.on('wed-context-menu', false);

    if (post_context_handler !== undefined)
        $post.on('wed-context-menu', post_context_handler);
    else
        $post.on('wed-context-menu', false);
};

Decorator.prototype._elementButtonClickHandler = function (ev) {
    var data = ev.data;
    data.$pre.addClass("_button_clicked");
    data.$post.addClass("_button_clicked");
};

Decorator.prototype._elementButtonUnclickHandler = function (ev) {
    var data = ev.data;
    data.$pre.removeClass("_button_clicked");
    data.$post.removeClass("_button_clicked");
};

Decorator.prototype._contextMenuHandler = function (
    at_start, wed_ev, ev) {
    var node = $(wed_ev.currentTarget).parents('._real').first().get(0);
    var menu_items = [];
    var editor = this._editor;
    var mode = editor.mode;
    if (node.parentNode !== editor.gui_root) {
        // We first gather the transformations that pertain to the
        // node to which the label belongs.

        var orig = util.getOriginalName(node);
        var trs = mode.getContextualActions(
            ["unwrap", "delete-element"], orig, node, 0);
        if (trs !== undefined) {
            trs.forEach(function (tr) {
                var data = {node: node, element_name: orig };
                var $a = $("" +
                           tr.getDescriptionFor(data) + "");
                $a.click(data, tr.bound_handler);
                menu_items.push($("
").append($a).get(0));
            }.bind(this));
        }

        // Then we check what could be done before the node (if the
        // user clicked on an start element label) or after the node
        // (if the user clicked on an end element label).
        var parent = node.parentNode;
        var index = Array.prototype.indexOf.call(parent.childNodes, node);

        // If we're on the end label, we want the events *after* the node.
        if (!at_start)
            index++;

        var tree_caret = editor.toDataCaret(parent, index);
        var handler = function(e) {
            // We must do that here so that we can move the caret
            // without it being destroyed when the selection is popped
            // by dismissContextMenu.
            editor.dismissContextMenu();
            editor.setDataCaret(tree_caret);
            e.data.tr.bound_handler(e);
        }.bind(this);
        editor.validator.possibleAt(
            tree_caret[0], tree_caret[1]).forEach(function (ev) {
                if (ev.params[0] !== "enterStartTag")
                    return;

                var unresolved = editor.resolver.unresolveName(
                    ev.params[1], ev.params[2]);

                var trs = mode.getContextualActions(
                    "insert", unresolved, tree_caret[0], tree_caret[1]);
                if (trs === undefined)
                    return;

                for(var tr_ix = 0, tr; (tr = trs[tr_ix]) !== undefined;
                    ++tr_ix) {
                    var data = {tr: tr, element_name: unresolved };
                    var $a = $("" +
                               tr.getDescriptionFor(data) +
                               (at_start ? " before this element":
                                " after this element")
                               + "");
                    $a.click(data, handler);
                    menu_items.push($("

").append($a).get(0));
                }
            }.bind(this));

        // There's no menu to display, so let the event bubble up.
        if (menu_items === 0)
            return true;

        editor.displayContextMenu(ev.pageX, ev.pageY, menu_items);
        return false;
    }

    return true;
};

});
<|endoftext|>


<commit_before>var ytdl = require('ytdl-core');

module.exports = YoutubeTrack = function(vid, info) {
  this.vid = vid;
  this.title = info.title;
  this.author = info.author;
  this.viewCount = info.viewCount || info.view_count;
  this.lengthSeconds = info.lengthSeconds || info.length_seconds;
};

YoutubeTrack.getInfoFromVid = function(vid, m, cb) {
  var requestUrl = 'http://www.youtube.com/watch?v=' + vid;
  ytdl.getInfo(requestUrl, (err, info) => {
    if (err) cb(err, undefined);
    else {
      var video = new YoutubeTrack(vid, info);
      video.userId = m.author.id;
      video.containedVideo = info;
      cb(undefined, video);
    }
  });
};

YoutubeTrack.prototype.getStream = function() {
  var options = {
    filter: (format) => format.container === 'mp4',
    quality: 'lowest',
  };

  return ytdl.downloadFromInfo(this.containedVideo, options);
};

YoutubeTrack.prototype.formatViewCount = function() {
  return this.viewCount ? this.viewCount.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : 'unknown';
};

YoutubeTrack.prototype.formatTime = function() {
  return `${Math.round((_this.lengthSeconds - Math.ceil(_this.lengthSeconds % 60)) / 60)}:${String('00' + Math.ceil(_this.lengthSeconds % 60)).slice(-2)}`;
};

YoutubeTrack.prototype.prettyPrint = function() {
  return `**${this.title}** by **${this.author}** *(${this.formatViewCount()} views)* [${this.formatTime()}]`;
};

YoutubeTrack.prototype.fullPrint = function() {
  return `${this.prettyPrint()}, added by <@${this.userId}>`;
};

YoutubeTrack.prototype.saveable = function() {
  return {
    vid: this.vid,
    title: this.title,
    author: video.author,
    viewCount: video.viewCount,
    lengthSeconds: video.lengthSeconds,
  };
};
<commit_msg>Replace some accidental references to _this<commit_after>var ytdl = require('ytdl-core');

module.exports = YoutubeTrack = function(vid, info) {
  this.vid = vid;
  this.title = info.title;
  this.author = info.author;
  this.viewCount = info.viewCount || info.view_count;
  this.lengthSeconds = info.lengthSeconds || info.length_seconds;
};

YoutubeTrack.getInfoFromVid = function(vid, m, cb) {
  var requestUrl = 'http://www.youtube.com/watch?v=' + vid;
  ytdl.getInfo(requestUrl, (err, info) => {
    if (err) cb(err, undefined);
    else {
      var video = new YoutubeTrack(vid, info);
      video.userId = m.author.id;
      video.containedVideo = info;
      cb(undefined, video);
    }
  });
};

YoutubeTrack.prototype.getStream = function() {
  var options = {
    filter: (format) => format.container === 'mp4',
    quality: 'lowest',
  };

  return ytdl.downloadFromInfo(this.containedVideo, options);
};

YoutubeTrack.prototype.formatViewCount = function() {
  return this.viewCount ? this.viewCount.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : 'unknown';
};

YoutubeTrack.prototype.formatTime = function() {
  return `${Math.round((this.lengthSeconds - Math.ceil(this.lengthSeconds % 60)) / 60)}:${String('00' + Math.ceil(this.lengthSeconds % 60)).slice(-2)}`;
};

YoutubeTrack.prototype.prettyPrint = function() {
  return `**${this.title}** by **${this.author}** *(${this.formatViewCount()} views)* [${this.formatTime()}]`;
};

YoutubeTrack.prototype.fullPrint = function() {
  return `${this.prettyPrint()}, added by <@${this.userId}>`;
};

YoutubeTrack.prototype.saveable = function() {
  return {
    vid: this.vid,
    title: this.title,
    author: video.author,
    viewCount: video.viewCount,
    lengthSeconds: video.lengthSeconds,
  };
};
<|endoftext|>


<commit_before>console.log('----------------------------------------------------------------------------------------------')
console.log('`DeprecationWarning: loaderUtils.parseQuery()` will be solved when babel-loader 7 is released.')
console.log('----------------------------------------------------------------------------------------------')

const path = require('path')
const webpack = require('webpack')
const fs = require('fs-extra')
const walkSync = require('walk-sync')

const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin')
const reactTemplatePlugin = require('../webpack-plugins/react-template-plugin')
const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin')
const sourceMapPlugin = require('../webpack-plugins/source-map-plugin')
const watchContextPlugin = require('../webpack-plugins/watch-context-plugin')
const hotModuleReplacementPlugin = require('../webpack-plugins/hot-module-replacement-plugin')
const loadDirectoryPlugin = require('../webpack-plugins/load-directory-plugin')
const absolutePathResolverPlugin = require('../webpack-resolver-plugins/absolute-path-resolver-plugin')

const babelLoader = {
  loader: 'babel-loader',
  options: {
    babelrc: false, // this needs to be false, any other value will cause .babelrc to interfere with these settings
    presets: [['es2015', { modules: false }], 'react'],
    plugins: ['transform-decorators-legacy', 'transform-class-properties', 'transform-object-rest-spread']
  }
}

const cssLoader = {
  loader: 'css-loader'
}

const imageLoader = {
  loader: 'image-webpack-loader',
  options: {
    // bypassOnDebug: true,
    // gifsicle: {}, // https://github.com/imagemin/imagemin-gifsicle#options
    // mozjpeg: {}, // https://github.com/imagemin/imagemin-mozjpeg#options
    // pngquant: {}, // https://github.com/imagemin/imagemin-pngquant#options
    // optipng: {}, // https://github.com/imagemin/imagemin-optipng#options
    // svgo: {} // https://github.com/imagemin/imagemin-svgo#options
  }
}

const imageSizeLoader = {
  loader: 'image-maxsize-webpack-loader',
  options: { useImageMagick: true }
}

const keepNameFileLoader = {
  loader: 'file-loader',
  options: { name: '[path][name].[ext]' }
}

const toJsonFileLoader = {
  loader: 'to-json-file-loader'
}

module.exports = function build({ watch }) {

  const target = path.resolve(process.cwd(), 'target')
  fs.removeSync(target)

  const srcDir = path.resolve(process.cwd(), 'src')

  const publicDir = path.resolve(srcDir, 'public')

  function createCompiler(entries) {
    return webpack({
      entry: entries,
      output: {
        filename: '[name]',
        path: target,
        libraryTarget: 'umd2' //'commonjs2'
      },
      externals: {
        react: {
          commonjs: 'react',
          commonjs2: 'react',
          root: 'React'
        },
        'react-dom': {
          commonjs: 'react-dom',
          commonjs2: 'react-dom',
          root: 'ReactDOM'
        },
        'react-dom/server': {
          commonjs: 'react-dom/server',
          commonjs2: 'react-dom/server'
        }
      },
      resolve: {
        extensions: ['.js', '.html.js'],
        modules: [srcDir, 'node_modules'],
        plugins: [absolutePathResolverPlugin(srcDir)]
      },
      resolveLoader: {
        modules: [path.resolve(__dirname, '../webpack-loaders'), "node_modules"]
      },
      context: srcDir,
      module: {
        // noParse: https://webpack.js.org/configuration/module/#module-noparse
        rules: [{ oneOf: [

          {
            test: [new RegExp('^' + publicDir)],
            oneOf: [
              {
                test: /\.css$/,
                loaders: [toJsonFileLoader, cssLoader]
              },

              {
                test: /\.svg$/,
                loaders: [
                  keepNameFileLoader,
                  imageLoader
                ]
              },

              {
                test: /\.(jpe?g|png|gif)$/,
                loaders: [keepNameFileLoader, imageLoader, imageSizeLoader]
              },

              {
                loaders: [keepNameFileLoader]
              }
            ]
          },

          {
            test: /\.json$/,
            loaders: []
          },

          {
            test: /\.entry\.css$/,
            loaders: [toJsonFileLoader, cssLoader]
          },

          {
            test: /\.css$/,
            loaders: ['json-loader', cssLoader]
          },

          {
            test: /(\.html\.js|\.js)$/,
            loaders: [babelLoader]
          },

          {
            test: /\.svg$/,
            loaders: [
              {
                loader: 'url-loader',
                options: { limit: 5000 }
              },
              imageLoader
            ]
          },

          {
            test: /\.(jpe?g|png|gif)$/,
            loaders: [
              {
                loader: 'url-loader',
                options: { limit: 5000 }
              },
              imageLoader,
              imageSizeLoader
            ]
          },

          {
            loader: 'file-loader'
          }

        ]}]
      },
      plugins: [
        watchContextPlugin(),
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }),
        new webpack.ProvidePlugin({
          React: 'react',
          Component: ['react', 'Component']
        }),
        sourceMapPlugin(),
        reactTemplatePlugin(entries),
        reactUniversalPlugin(),
        mergeCssPlugin(),
        watch && hotModuleReplacementPlugin(),
        fs.existsSync(publicDir) && loadDirectoryPlugin(publicDir)
      ].filter(Boolean)
    })
  }

  try {
    if (watch) startWatching(compilationComplete)
    else runOnce(compilationComplete)

    function compilationComplete(err, stats) {
      if (err) {
        console.error(err.stack || err)
        if (err.details) console.error(err.details)
        return
      }

      console.log(stats.toString({ colors: true }))
    }

    function runOnce() {
      const compiler = createCompiler(gatherEntries())
      compiler.run(compilationComplete)
    }

    function startWatching(callback) {
      let watching
      let entries
      start(gatherEntries())

      function start(newEntries) {
        entries = newEntries
        const compiler = createCompiler(entries)
        watching = compiler.watch({}, onWatchTriggered)
      }

      function onWatchTriggered(err, stats) {
        callback(err, stats)

        const newEntries = gatherEntries()
        const [oldKeys, newKeys] = [Object.keys(entries), Object.keys(newEntries)]
        const entriesChanged = !oldKeys.every(x => newKeys.includes(x)) || !newKeys.every(x => oldKeys.includes(x))

        if (entriesChanged) {
          console.log('Entries changed, restarting watch')
          watching.close(() => { start(newEntries) })
        }
        console.log('\nWaiting for file changes...\n')
      }
    }
  } catch (e) { console.error(e.message) }

  function gatherEntries() {
    return walkSync(srcDir, { globs: ['**/*.html.js', '**/*.entry.js', '**/*.entry.css'] }).reduce(
      (result, entry) => (
        result[entry.replace('.html.js', '')] = './' + entry, result),
      {}
    )
  }
}
<commit_msg>Set public path configuration in order to resolve dependencies from the root<commit_after>console.log('----------------------------------------------------------------------------------------------')
console.log('`DeprecationWarning: loaderUtils.parseQuery()` will be solved when babel-loader 7 is released.')
console.log('----------------------------------------------------------------------------------------------')

const path = require('path')
const webpack = require('webpack')
const fs = require('fs-extra')
const walkSync = require('walk-sync')

const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin')
const reactTemplatePlugin = require('../webpack-plugins/react-template-plugin')
const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin')
const sourceMapPlugin = require('../webpack-plugins/source-map-plugin')
const watchContextPlugin = require('../webpack-plugins/watch-context-plugin')
const hotModuleReplacementPlugin = require('../webpack-plugins/hot-module-replacement-plugin')
const loadDirectoryPlugin = require('../webpack-plugins/load-directory-plugin')
const absolutePathResolverPlugin = require('../webpack-resolver-plugins/absolute-path-resolver-plugin')

const babelLoader = {
  loader: 'babel-loader',
  options: {
    babelrc: false, // this needs to be false, any other value will cause .babelrc to interfere with these settings
    presets: [['es2015', { modules: false }], 'react'],
    plugins: ['transform-decorators-legacy', 'transform-class-properties', 'transform-object-rest-spread']
  }
}

const cssLoader = {
  loader: 'css-loader'
}

const imageLoader = {
  loader: 'image-webpack-loader',
  options: {
    // bypassOnDebug: true,
    // gifsicle: {}, // https://github.com/imagemin/imagemin-gifsicle#options
    // mozjpeg: {}, // https://github.com/imagemin/imagemin-mozjpeg#options
    // pngquant: {}, // https://github.com/imagemin/imagemin-pngquant#options
    // optipng: {}, // https://github.com/imagemin/imagemin-optipng#options
    // svgo: {} // https://github.com/imagemin/imagemin-svgo#options
  }
}

const imageSizeLoader = {
  loader: 'image-maxsize-webpack-loader',
  options: { useImageMagick: true }
}

const keepNameFileLoader = {
  loader: 'file-loader',
  options: { name: '[path][name].[ext]' }
}

const toJsonFileLoader = {
  loader: 'to-json-file-loader'
}

module.exports = function build({ watch }) {

  const target = path.resolve(process.cwd(), 'target')
  fs.removeSync(target)

  const srcDir = path.resolve(process.cwd(), 'src')

  const publicDir = path.resolve(srcDir, 'public')

  function createCompiler(entries) {
    return webpack({
      entry: entries,
      output: {
        filename: '[name]',
        path: target,
        publicPath: '/',
        libraryTarget: 'umd2' //'commonjs2'
      },
      externals: {
        react: {
          commonjs: 'react',
          commonjs2: 'react',
          root: 'React'
        },
        'react-dom': {
          commonjs: 'react-dom',
          commonjs2: 'react-dom',
          root: 'ReactDOM'
        },
        'react-dom/server': {
          commonjs: 'react-dom/server',
          commonjs2: 'react-dom/server'
        }
      },
      resolve: {
        extensions: ['.js', '.html.js'],
        modules: [srcDir, 'node_modules'],
        plugins: [absolutePathResolverPlugin(srcDir)]
      },
      resolveLoader: {
        modules: [path.resolve(__dirname, '../webpack-loaders'), "node_modules"]
      },
      context: srcDir,
      module: {
        // noParse: https://webpack.js.org/configuration/module/#module-noparse
        rules: [{ oneOf: [

          {
            test: [new RegExp('^' + publicDir)],
            oneOf: [
              {
                test: /\.css$/,
                loaders: [toJsonFileLoader, cssLoader]
              },

              {
                test: /\.svg$/,
                loaders: [
                  keepNameFileLoader,
                  imageLoader
                ]
              },

              {
                test: /\.(jpe?g|png|gif)$/,
                loaders: [keepNameFileLoader, imageLoader, imageSizeLoader]
              },

              {
                loaders: [keepNameFileLoader]
              }
            ]
          },

          {
            test: /\.json$/,
            loaders: []
          },

          {
            test: /\.entry\.css$/,
            loaders: [toJsonFileLoader, cssLoader]
          },

          {
            test: /\.css$/,
            loaders: ['json-loader', cssLoader]
          },

          {
            test: /(\.html\.js|\.js)$/,
            loaders: [babelLoader]
          },

          {
            test: /\.svg$/,
            loaders: [
              {
                loader: 'url-loader',
                options: { limit: 5000 }
              },
              imageLoader
            ]
          },

          {
            test: /\.(jpe?g|png|gif)$/,
            loaders: [
              {
                loader: 'url-loader',
                options: { limit: 5000 }
              },
              imageLoader,
              imageSizeLoader
            ]
          },

          {
            loader: 'file-loader'
          }

        ]}]
      },
      plugins: [
        watchContextPlugin(),
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }),
        new webpack.ProvidePlugin({
          React: 'react',
          Component: ['react', 'Component']
        }),
        sourceMapPlugin(),
        reactTemplatePlugin(entries),
        reactUniversalPlugin(),
        mergeCssPlugin(),
        watch && hotModuleReplacementPlugin(),
        fs.existsSync(publicDir) && loadDirectoryPlugin(publicDir)
      ].filter(Boolean)
    })
  }

  try {
    if (watch) startWatching(compilationComplete)
    else runOnce(compilationComplete)

    function compilationComplete(err, stats) {
      if (err) {
        console.error(err.stack || err)
        if (err.details) console.error(err.details)
        return
      }

      console.log(stats.toString({ colors: true }))
    }

    function runOnce() {
      const compiler = createCompiler(gatherEntries())
      compiler.run(compilationComplete)
    }

    function startWatching(callback) {
      let watching
      let entries
      start(gatherEntries())

      function start(newEntries) {
        entries = newEntries
        const compiler = createCompiler(entries)
        watching = compiler.watch({}, onWatchTriggered)
      }

      function onWatchTriggered(err, stats) {
        callback(err, stats)

        const newEntries = gatherEntries()
        const [oldKeys, newKeys] = [Object.keys(entries), Object.keys(newEntries)]
        const entriesChanged = !oldKeys.every(x => newKeys.includes(x)) || !newKeys.every(x => oldKeys.includes(x))

        if (entriesChanged) {
          console.log('Entries changed, restarting watch')
          watching.close(() => { start(newEntries) })
        }
        console.log('\nWaiting for file changes...\n')
      }
    }
  } catch (e) { console.error(e.message) }

  function gatherEntries() {
    return walkSync(srcDir, { globs: ['**/*.html.js', '**/*.entry.js', '**/*.entry.css'] }).reduce(
      (result, entry) => (
        result[entry.replace('.html.js', '')] = './' + entry, result),
      {}
    )
  }
}
<|endoftext|>


<commit_before>// @ts-ignore - Better logging for deprecation and other errors
process.traceDeprecation = true
process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled rejection of:\n', p, '\nReason:\n', reason)
})

let caseSensitive = false
try {
  require('./CaSe-SeNsItIvE')
  caseSensitive = false
} catch (e) {
  caseSensitive = true
} finally {
  if (!caseSensitive) throw new Error(`@kaliber/build will not run on a filesystem that is case-insensitive`)
}

const findYarnWorkspaceRoot = require('find-yarn-workspace-root')
const fs = require('fs-extra')
const nodeExternals = require('webpack-node-externals')
const path = require('path')
const walkSync = require('walk-sync')
const webpack = require('webpack')

const chunkManifestPlugin = require('../webpack-plugins/chunk-manifest-plugin')
const configLoaderPlugin = require('../webpack-plugins/config-loader-plugin')
const copyUnusedFilesPlugin = require('../webpack-plugins/copy-unused-files-plugin')
const hotCssReplacementPlugin = require('../webpack-plugins/hot-css-replacement-plugin')
const hotModuleReplacementPlugin = require('../webpack-plugins/hot-module-replacement-plugin')
const makeAdditionalEntriesPlugin = require('../webpack-plugins/make-additional-entries-plugin')
const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin')
const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin')
const sourceMapPlugin = require('../webpack-plugins/source-map-plugin')
const templatePlugin = require('../webpack-plugins/template-plugin')
const watchContextPlugin = require('../webpack-plugins/watch-context-plugin')
const websocketCommunicationPlugin = require('../webpack-plugins/websocket-communication-plugin')
const webWorkerPlugin = require('../webpack-plugins/web-worker-plugin')
const noKaliberConfigPlugin = require('../webpack-plugins/no-kaliber-config-plugin')

const absolutePathResolverPlugin = require('../webpack-resolver-plugins/absolute-path-resolver-plugin')
const fragmentResolverPlugin = require('../webpack-resolver-plugins/fragment-resolver-plugin')

const ExtendedAPIPlugin = require('webpack/lib/ExtendedAPIPlugin')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const TimeFixPlugin = require('time-fix-plugin') // https://github.com/webpack/watchpack/issues/25
const TerserPlugin = require('terser-webpack-plugin')

const templateRenderers = require('./getTemplateRenderers')

const isProduction = process.env.NODE_ENV === 'production'

const { kaliber: { compileWithBabel: userDefinedcompileWithBabel = [], publicPath = '/', symlinks = true } = {} } = require('@kaliber/config')

const recognizedTemplates = Object.keys(templateRenderers)

const kaliberBuildClientModules = [/(@kaliber\/build\/lib\/(stylesheet|javascript|polyfill|withPolyfill|hot-module-replacement-client|rollbar|universalComponents)|ansi-regex)/]
const compileWithBabel = kaliberBuildClientModules.concat(userDefinedcompileWithBabel)

const babelLoader = {
  loader: 'babel-loader',
  options: {
    cacheDirectory: './.babelcache/',
    cacheCompression: false,
    babelrc: false, // this needs to be false, any other value will cause .babelrc to interfere with these settings
    presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
    plugins: [
      '@babel/syntax-dynamic-import',
      '@babel/syntax-optional-chaining',
      ['@babel/proposal-decorators', { legacy: true }],
      '@babel/proposal-class-properties',
      '@babel/proposal-object-rest-spread',
      '@babel/transform-async-to-generator',
      ['@babel/transform-runtime', {
        'helpers': false,
        'regenerator': true
      }]
    ]
  }
}

const cssLoaderGlobalScope = {
  loader: 'css-loader',
  options: { globalScopeBehaviour: true }
}

const cssLoader = {
  loader: 'css-loader'
}

const cssLoaderMinifyOnly = {
  loader: 'css-loader',
  options: { minifyOnly: true }
}

const imageLoader = {
  loader: 'image-webpack-loader',
  options: {
    // bypassOnDebug: true,
    // gifsicle: {}, // https://github.com/imagemin/imagemin-gifsicle#options
    // mozjpeg: {}, // https://github.com/imagemin/imagemin-mozjpeg#options
    // pngquant: {}, // https://github.com/imagemin/imagemin-pngquant#options
    // optipng: {}, // https://github.com/imagemin/imagemin-optipng#options
    svgo: { enabled: false } // https://github.com/imagemin/imagemin-svgo#options
  }
}

const imageSizeLoader = {
  loader: 'image-maxsize-webpack-loader',
  options: { useImageMagick: true }
}

const urlLoader = {
  loader: 'url-loader',
  options: { limit: 5000, esModule: false }
}

const fileLoader = {
  loader: 'file-loader',
  options: { esModule: false }
}

const rawLoader = {
  loader: 'raw-loader',
  options: { esModule: false }
}

module.exports = function build({ watch }) {

  const cwd = process.cwd()

  const srcDir = path.resolve(cwd, 'src')
  const yarnWorkspaceDir = findYarnWorkspaceRoot(cwd)
  const targetDir = path.resolve(cwd, 'target')
  fs.removeSync(targetDir)

  const mode = isProduction ? 'production' : 'development'
  const outputPath = path.join(targetDir, publicPath)

  function nodeOptions() {
    return {
      mode,
      target: 'node',
      context: srcDir,
      devtool: false,
      output: {
        filename: '[name]',
        chunkFilename: '[name]-[hash].js',
        path: outputPath,
        publicPath,
        libraryTarget: 'commonjs2'
      },
      externals: [
        nodeExternals(externalConfForModulesDir('node_modules')),
        yarnWorkspaceDir && nodeExternals(externalConfForModulesDir(path.resolve(yarnWorkspaceDir, 'node_modules')))
      ].filter(Boolean),
      optimization: {
        minimize: false,
        namedChunks: false,
        splitChunks: false
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: moduleOptions(),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().node()
      ]
    }
  }

  function webOptions() {
    return {
      mode,
      target: 'web',
      context: srcDir,
      devtool: false,
      entry: false,
      output: {
        filename: '[id].[hash].js',
        chunkFilename: '[id].[hash].js',
        path: outputPath,
        publicPath
      },
      optimization: {
        namedChunks: false,
        runtimeChunk: 'single',
        minimize: isProduction,
        minimizer: [
          new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true
          })
        ],
        splitChunks: {
          chunks: 'all',
          minSize: 10000
        }
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: Object.assign({
        unsafeCache: false
      }, moduleOptions()),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().web()
      ]
    }
  }

  function webWorkerOptions() {
    return {
      mode,
      target: 'webworker',
      context: srcDir,
      devtool: false,
      entry: false,
      output: {
        filename: '[id].[hash].js',
        chunkFilename: '[id].[hash].js',
        path: outputPath,
        publicPath
      },
      optimization: {
        minimize: isProduction,
        minimizer: [
          new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true
          })
        ],
        namedChunks: false,
        splitChunks: false
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: Object.assign({
        unsafeCache: false
      }, moduleOptions()),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().webWorker()
      ]
    }
  }

  function resolveOptions() {
    return {
      extensions: ['.js', '.mjs'],
      modules: ['node_modules'],
      plugins: [absolutePathResolverPlugin(srcDir), fragmentResolverPlugin()],
      symlinks,
    }
  }

  function resolveLoaderOptions() {
    return {
      modules: [
        path.resolve(__dirname, '../webpack-loaders'),
        'node_modules'
      ]
    }
  }

  function moduleOptions() {
    return {
      rules: [{ oneOf: [

        {
          test: /\.raw\.[^.]+$/,
          loaders: [rawLoader]
        },

        {
          type: 'json',
          test: /\.json$/,
          loaders: []
        },

        {
          test: /\.entry\.css$/,
          loaders: [cssLoaderGlobalScope]
        },

        {
          resource: {
            test: /\.css$/,
            or: [{ exclude: /node_modules/ }, ...compileWithBabel],
          },
          loaders: ['json-loader', cssLoader],
        },

        {
          test: /\.css$/,
          loaders: [cssLoaderMinifyOnly]
        },

        {
          test: /\.js$/,
          resourceQuery: /transpiled-javascript-string/,
          loaders: [rawLoader, babelLoader]
        },

        {
          resource: {
            test: /(\.html\.js|\.js|\.mjs)$/,
            or: [{ exclude: /node_modules/ }, ...compileWithBabel],
          },
          loaders: [babelLoader]
        },

        {
          test: /(\.js|\.mjs)$/
        },

        {
          test: /\.svg$/,
          resourceQuery: /fragment/,
          loaders: ['fragment-loader']
        },

        {
          test: /\.svg$/,
          loaders: [
            urlLoader,
            imageLoader
          ]
        },

        {
          test: /\.(jpe?g|png|gif)$/,
          loaders: [
            urlLoader,
            'cache-loader',
            isProduction && imageLoader,
            imageSizeLoader
          ].filter(Boolean)
        },

        {
          loader: fileLoader
        }

      ] }]
    }
  }

  function pluginsOptions() {
    return {
      all: () => [
        ProgressBarPlugin(),
        makeAdditionalEntriesPlugin(),
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
          'process.env.WATCH': watch
        }),
        new webpack.ProvidePlugin({
          React: 'react',
          Component: ['react', 'Component'],
          cx: 'classnames',
        }),
        sourceMapPlugin({ sourceRoot: cwd }),
      ].filter(Boolean),
      node: () => [
        watch && websocketCommunicationPlugin(),
        new TimeFixPlugin(),
        new ExtendedAPIPlugin(),
        configLoaderPlugin(),
        watchContextPlugin(),
        reactUniversalPlugin(webOptions()),  // claims .entry.js
        templatePlugin(templateRenderers), // does work on .*.js
        mergeCssPlugin(),
        copyUnusedFilesPlugin(),
        watch && hotCssReplacementPlugin(),
        webWorkerPlugin.handleWebWorkerImports,
      ].filter(Boolean),
      web: () => [
        watch && websocketCommunicationPlugin(),
        chunkManifestPlugin({ filename: 'chunk-manifest.json' }),
        watch && hotModuleReplacementPlugin(),
        webWorkerPlugin(webWorkerOptions()),
        noKaliberConfigPlugin(),
      ].filter(Boolean),
      webWorker: () => [
        chunkManifestPlugin({ filename: 'web-worker-manifest.json' }),
        noKaliberConfigPlugin(),
      ].filter(Boolean),
    }
  }

  function externalConfForModulesDir(modulesDir) {
    return {
      modulesDir,
      allowlist: ['@kaliber/config', ...compileWithBabel, /\.css$/]
    }
  }

  try {
    if (watch) startWatching(compilationComplete)
    else runOnce(compilationComplete)

    function createCompiler(entries) {
      return webpack(Object.assign({
        entry: entries
      }, nodeOptions()))
    }

    function compilationComplete(err, stats) {
      if (err) {
        console.error(err.stack || err)
        if (err.details) console.error(err.details)
        if (!watch) process.exit(1)
        return
      }

      console.log(stats.toString({
        colors: true,
        chunksSort: 'name',
        assetsSort: 'name',
        modulesSort: 'name',
        excludeModules: (name, module) => !module.external
      }))

      if (!watch && stats.hasErrors()) process.exitCode = 2
    }

    function runOnce(callback) {
      const compiler = createCompiler(gatherEntries())
      compiler.run(callback)
    }

    function startWatching(callback) {
      let watching
      let entries
      start(gatherEntries())

      function start(newEntries) {
        entries = newEntries
        const compiler = createCompiler(entries)
        watching = compiler.watch({}, onWatchTriggered)
      }

      function onWatchTriggered(err, stats) {
        callback(err, stats)

        const newEntries = gatherEntries()
        const [oldKeys, newKeys] = [Object.keys(entries), Object.keys(newEntries)]
        const entriesChanged = !oldKeys.every(x => newKeys.includes(x)) || !newKeys.every(x => oldKeys.includes(x))

        console.log('\nWaiting for file changes...\n')

        if (entriesChanged) {
          console.log('Entries changed, restarting watch')
          watching.close(() => { start(newEntries) })
        }
      }
    }
  } catch (e) { console.error(e) }

  function gatherEntries() {
    const template = recognizedTemplates.join('|')
    const globs = [`**/*.@(${template}).js`, '**/*.entry.js', '**/*.entry.css']
    return walkSync(srcDir, { globs }).reduce(
      (result, entry) => ((result[entry] = './' + entry), result),
      {}
    )
  }
}
<commit_msg>Force `mjs` to be treated as JavaScript<commit_after>// @ts-ignore - Better logging for deprecation and other errors
process.traceDeprecation = true
process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled rejection of:\n', p, '\nReason:\n', reason)
})

let caseSensitive = false
try {
  require('./CaSe-SeNsItIvE')
  caseSensitive = false
} catch (e) {
  caseSensitive = true
} finally {
  if (!caseSensitive) throw new Error(`@kaliber/build will not run on a filesystem that is case-insensitive`)
}

const findYarnWorkspaceRoot = require('find-yarn-workspace-root')
const fs = require('fs-extra')
const nodeExternals = require('webpack-node-externals')
const path = require('path')
const walkSync = require('walk-sync')
const webpack = require('webpack')

const chunkManifestPlugin = require('../webpack-plugins/chunk-manifest-plugin')
const configLoaderPlugin = require('../webpack-plugins/config-loader-plugin')
const copyUnusedFilesPlugin = require('../webpack-plugins/copy-unused-files-plugin')
const hotCssReplacementPlugin = require('../webpack-plugins/hot-css-replacement-plugin')
const hotModuleReplacementPlugin = require('../webpack-plugins/hot-module-replacement-plugin')
const makeAdditionalEntriesPlugin = require('../webpack-plugins/make-additional-entries-plugin')
const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin')
const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin')
const sourceMapPlugin = require('../webpack-plugins/source-map-plugin')
const templatePlugin = require('../webpack-plugins/template-plugin')
const watchContextPlugin = require('../webpack-plugins/watch-context-plugin')
const websocketCommunicationPlugin = require('../webpack-plugins/websocket-communication-plugin')
const webWorkerPlugin = require('../webpack-plugins/web-worker-plugin')
const noKaliberConfigPlugin = require('../webpack-plugins/no-kaliber-config-plugin')

const absolutePathResolverPlugin = require('../webpack-resolver-plugins/absolute-path-resolver-plugin')
const fragmentResolverPlugin = require('../webpack-resolver-plugins/fragment-resolver-plugin')

const ExtendedAPIPlugin = require('webpack/lib/ExtendedAPIPlugin')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const TimeFixPlugin = require('time-fix-plugin') // https://github.com/webpack/watchpack/issues/25
const TerserPlugin = require('terser-webpack-plugin')

const templateRenderers = require('./getTemplateRenderers')

const isProduction = process.env.NODE_ENV === 'production'

const { kaliber: { compileWithBabel: userDefinedcompileWithBabel = [], publicPath = '/', symlinks = true } = {} } = require('@kaliber/config')

const recognizedTemplates = Object.keys(templateRenderers)

const kaliberBuildClientModules = [/(@kaliber\/build\/lib\/(stylesheet|javascript|polyfill|withPolyfill|hot-module-replacement-client|rollbar|universalComponents)|ansi-regex)/]
const compileWithBabel = kaliberBuildClientModules.concat(userDefinedcompileWithBabel)

const babelLoader = {
  loader: 'babel-loader',
  options: {
    cacheDirectory: './.babelcache/',
    cacheCompression: false,
    babelrc: false, // this needs to be false, any other value will cause .babelrc to interfere with these settings
    presets: [['@babel/preset-env', { modules: false }], '@babel/preset-react'],
    plugins: [
      '@babel/syntax-dynamic-import',
      '@babel/syntax-optional-chaining',
      ['@babel/proposal-decorators', { legacy: true }],
      '@babel/proposal-class-properties',
      '@babel/proposal-object-rest-spread',
      '@babel/transform-async-to-generator',
      ['@babel/transform-runtime', {
        'helpers': false,
        'regenerator': true
      }]
    ]
  }
}

const cssLoaderGlobalScope = {
  loader: 'css-loader',
  options: { globalScopeBehaviour: true }
}

const cssLoader = {
  loader: 'css-loader'
}

const cssLoaderMinifyOnly = {
  loader: 'css-loader',
  options: { minifyOnly: true }
}

const imageLoader = {
  loader: 'image-webpack-loader',
  options: {
    // bypassOnDebug: true,
    // gifsicle: {}, // https://github.com/imagemin/imagemin-gifsicle#options
    // mozjpeg: {}, // https://github.com/imagemin/imagemin-mozjpeg#options
    // pngquant: {}, // https://github.com/imagemin/imagemin-pngquant#options
    // optipng: {}, // https://github.com/imagemin/imagemin-optipng#options
    svgo: { enabled: false } // https://github.com/imagemin/imagemin-svgo#options
  }
}

const imageSizeLoader = {
  loader: 'image-maxsize-webpack-loader',
  options: { useImageMagick: true }
}

const urlLoader = {
  loader: 'url-loader',
  options: { limit: 5000, esModule: false }
}

const fileLoader = {
  loader: 'file-loader',
  options: { esModule: false }
}

const rawLoader = {
  loader: 'raw-loader',
  options: { esModule: false }
}

module.exports = function build({ watch }) {

  const cwd = process.cwd()

  const srcDir = path.resolve(cwd, 'src')
  const yarnWorkspaceDir = findYarnWorkspaceRoot(cwd)
  const targetDir = path.resolve(cwd, 'target')
  fs.removeSync(targetDir)

  const mode = isProduction ? 'production' : 'development'
  const outputPath = path.join(targetDir, publicPath)

  function nodeOptions() {
    return {
      mode,
      target: 'node',
      context: srcDir,
      devtool: false,
      output: {
        filename: '[name]',
        chunkFilename: '[name]-[hash].js',
        path: outputPath,
        publicPath,
        libraryTarget: 'commonjs2'
      },
      externals: [
        nodeExternals(externalConfForModulesDir('node_modules')),
        yarnWorkspaceDir && nodeExternals(externalConfForModulesDir(path.resolve(yarnWorkspaceDir, 'node_modules')))
      ].filter(Boolean),
      optimization: {
        minimize: false,
        namedChunks: false,
        splitChunks: false
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: moduleOptions(),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().node()
      ]
    }
  }

  function webOptions() {
    return {
      mode,
      target: 'web',
      context: srcDir,
      devtool: false,
      entry: false,
      output: {
        filename: '[id].[hash].js',
        chunkFilename: '[id].[hash].js',
        path: outputPath,
        publicPath
      },
      optimization: {
        namedChunks: false,
        runtimeChunk: 'single',
        minimize: isProduction,
        minimizer: [
          new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true
          })
        ],
        splitChunks: {
          chunks: 'all',
          minSize: 10000
        }
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: Object.assign({
        unsafeCache: false
      }, moduleOptions()),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().web()
      ]
    }
  }

  function webWorkerOptions() {
    return {
      mode,
      target: 'webworker',
      context: srcDir,
      devtool: false,
      entry: false,
      output: {
        filename: '[id].[hash].js',
        chunkFilename: '[id].[hash].js',
        path: outputPath,
        publicPath
      },
      optimization: {
        minimize: isProduction,
        minimizer: [
          new TerserPlugin({
            cache: true,
            parallel: true,
            sourceMap: true
          })
        ],
        namedChunks: false,
        splitChunks: false
      },
      resolve: resolveOptions(),
      resolveLoader: resolveLoaderOptions(),
      module: Object.assign({
        unsafeCache: false
      }, moduleOptions()),
      plugins: [
        ...pluginsOptions().all(),
        ...pluginsOptions().webWorker()
      ]
    }
  }

  function resolveOptions() {
    return {
      extensions: ['.js', '.mjs'],
      modules: ['node_modules'],
      plugins: [absolutePathResolverPlugin(srcDir), fragmentResolverPlugin()],
      symlinks,
    }
  }

  function resolveLoaderOptions() {
    return {
      modules: [
        path.resolve(__dirname, '../webpack-loaders'),
        'node_modules'
      ]
    }
  }

  function moduleOptions() {
    return {
      rules: [{ oneOf: [

        {
          test: /\.raw\.[^.]+$/,
          loaders: [rawLoader]
        },

        {
          type: 'json',
          test: /\.json$/,
          loaders: []
        },

        {
          test: /\.entry\.css$/,
          loaders: [cssLoaderGlobalScope]
        },

        {
          resource: {
            test: /\.css$/,
            or: [{ exclude: /node_modules/ }, ...compileWithBabel],
          },
          loaders: ['json-loader', cssLoader],
        },

        {
          test: /\.css$/,
          loaders: [cssLoaderMinifyOnly]
        },

        {
          test: /\.js$/,
          resourceQuery: /transpiled-javascript-string/,
          loaders: [rawLoader, babelLoader]
        },

        {
          resource: {
            test: /(\.html\.js|\.js|\.mjs)$/,
            or: [{ exclude: /node_modules/ }, ...compileWithBabel],
          },
          loaders: [babelLoader]
        },

        {
          test: /(\.js|\.mjs)$/,
          type: 'javascript/auto',
        },

        {
          test: /\.svg$/,
          resourceQuery: /fragment/,
          loaders: ['fragment-loader']
        },

        {
          test: /\.svg$/,
          loaders: [
            urlLoader,
            imageLoader
          ]
        },

        {
          test: /\.(jpe?g|png|gif)$/,
          loaders: [
            urlLoader,
            'cache-loader',
            isProduction && imageLoader,
            imageSizeLoader
          ].filter(Boolean)
        },

        {
          loader: fileLoader
        }

      ] }]
    }
  }

  function pluginsOptions() {
    return {
      all: () => [
        ProgressBarPlugin(),
        makeAdditionalEntriesPlugin(),
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
          'process.env.WATCH': watch
        }),
        new webpack.ProvidePlugin({
          React: 'react',
          Component: ['react', 'Component'],
          cx: 'classnames',
        }),
        sourceMapPlugin({ sourceRoot: cwd }),
      ].filter(Boolean),
      node: () => [
        watch && websocketCommunicationPlugin(),
        new TimeFixPlugin(),
        new ExtendedAPIPlugin(),
        configLoaderPlugin(),
        watchContextPlugin(),
        reactUniversalPlugin(webOptions()),  // claims .entry.js
        templatePlugin(templateRenderers), // does work on .*.js
        mergeCssPlugin(),
        copyUnusedFilesPlugin(),
        watch && hotCssReplacementPlugin(),
        webWorkerPlugin.handleWebWorkerImports,
      ].filter(Boolean),
      web: () => [
        watch && websocketCommunicationPlugin(),
        chunkManifestPlugin({ filename: 'chunk-manifest.json' }),
        watch && hotModuleReplacementPlugin(),
        webWorkerPlugin(webWorkerOptions()),
        noKaliberConfigPlugin(),
      ].filter(Boolean),
      webWorker: () => [
        chunkManifestPlugin({ filename: 'web-worker-manifest.json' }),
        noKaliberConfigPlugin(),
      ].filter(Boolean),
    }
  }

  function externalConfForModulesDir(modulesDir) {
    return {
      modulesDir,
      allowlist: ['@kaliber/config', ...compileWithBabel, /\.css$/]
    }
  }

  try {
    if (watch) startWatching(compilationComplete)
    else runOnce(compilationComplete)

    function createCompiler(entries) {
      return webpack(Object.assign({
        entry: entries
      }, nodeOptions()))
    }

    function compilationComplete(err, stats) {
      if (err) {
        console.error(err.stack || err)
        if (err.details) console.error(err.details)
        if (!watch) process.exit(1)
        return
      }

      console.log(stats.toString({
        colors: true,
        chunksSort: 'name',
        assetsSort: 'name',
        modulesSort: 'name',
        excludeModules: (name, module) => !module.external
      }))

      if (!watch && stats.hasErrors()) process.exitCode = 2
    }

    function runOnce(callback) {
      const compiler = createCompiler(gatherEntries())
      compiler.run(callback)
    }

    function startWatching(callback) {
      let watching
      let entries
      start(gatherEntries())

      function start(newEntries) {
        entries = newEntries
        const compiler = createCompiler(entries)
        watching = compiler.watch({}, onWatchTriggered)
      }

      function onWatchTriggered(err, stats) {
        callback(err, stats)

        const newEntries = gatherEntries()
        const [oldKeys, newKeys] = [Object.keys(entries), Object.keys(newEntries)]
        const entriesChanged = !oldKeys.every(x => newKeys.includes(x)) || !newKeys.every(x => oldKeys.includes(x))

        console.log('\nWaiting for file changes...\n')

        if (entriesChanged) {
          console.log('Entries changed, restarting watch')
          watching.close(() => { start(newEntries) })
        }
      }
    }
  } catch (e) { console.error(e) }

  function gatherEntries() {
    const template = recognizedTemplates.join('|')
    const globs = [`**/*.@(${template}).js`, '**/*.entry.js', '**/*.entry.css']
    return walkSync(srcDir, { globs }).reduce(
      (result, entry) => ((result[entry] = './' + entry), result),
      {}
    )
  }
}
<|endoftext|>


<commit_before>'use strict'

function SettingsWorld() {
    this.__init__()
}

// Cell phone carriers.
const CELL_PHONE_CARRIERS = {
    'None'             : '',
    'AT&T'             : 'number@txt.att.net',
    'T-Mobile'         : 'number@tmomail.net',
    'Verizon'          : 'number@vtext.com',
    'Sprint'           : 'number@pm.sprint.com',
    'Virgin Mobile'    : 'number@vmobl.com',
    'Tracfone'         : 'number@mmst5.tracfone.com',
    'Metro PCS'        : 'number@mymetropcs.com',
    'Boost Mobile'     : 'number@myboostmobile.com',
    'Cricket'          : 'number@mms.cricketwireless.net',
    'Ptel'             : 'number@ptel.com',
    'Republic Wireless': 'number@text.republicwireless.com',
    'Google Fi'        : 'number@msg.fi.google.com',
    'Suncom'           : 'number@tms.suncom.com',
    'Ting'             : 'number@message.ting.com',
    'U.S. Cellular'    : 'number@email.uscc.net',
    'Consumer Cellular': 'number@cingularme.com',
    'C-Spire'          : 'number@cspire1.com',
    'Page Plus'        : 'number@vtext.com'
}

SettingsWorld.prototype = {

    previous_world: null,

    owner_entity: null,

    select_phone_carrier: function() {
        this.phone_carrier_list.set_to_visible()
    },

    selected_phone_carrier: function(selected_phone_carrier) {
        this.phone_carrier_list.set_to_invisible()
        l('The selected phone carrier is: ')
        l(selected_phone_carrier)
    },

    __init__: function() {
        this.owner_entity = null

        // Inherit world properties.
        World.call(this, 'SettingsWorld')

        var position = new THREE.Vector3(500, 500, 700)
        this.normal = new THREE.Vector3(-.5, 0, -.85)
        this.normal.normalize()
        this.profile_editor = new FloatingWall(1024, 512 / 2, position, this.normal, this)

        var create_entity_wall_title = this.profile_editor.add_floating_2d_text(1024 / 2, 'Profile Information', TYPE_TITLE, 1024 / -4, 2, 0, 0)
        create_entity_wall_title.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_editor.add_object_to_remove_later(create_entity_wall_title)

        var label_width = 1024 / 8
        var label_offset = (1024 / -4) - label_width / 2

        this.profile_name_label = this.profile_editor.add_floating_2d_text(label_width, 'Username', TYPE_INPUT_REGULAR, label_offset, 2, 3, 0)
        this.profile_name_label.engable = false
        this.profile_name_label.set_default_color(COLOR_TEXT_CONSTANT)
        //this.profile_editor.add_object_to_remove_later(profile_name)

        this.profile_name_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 3, 0)
        //this.profile_editor.add_object_to_remove_later(profile_name_input)

        this.profile_email_label = this.profile_editor.add_floating_2d_text(label_width, 'Email', TYPE_INPUT_REGULAR, label_offset, 2, 4, 0)
        this.profile_email_label.engable = false
        this.profile_email_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_email_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 4, 0)

        this.profile_phone_number_label = this.profile_editor.add_floating_2d_text(label_width, 'Phone Number', TYPE_INPUT_REGULAR, label_offset, 2, 5, 0)
        this.profile_phone_number_label.engable = false
        this.profile_phone_number_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_phone_number_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 5, 0)

        this.profile_phone_carrier_label = this.profile_editor.add_floating_2d_text(label_width, 'Phone Carrier', TYPE_INPUT_REGULAR, label_offset, 2, 6, 0)
        this.profile_phone_carrier_label.engable = false
        this.profile_phone_carrier_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_phone_carrier_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 6, 0)
        this.profile_phone_carrier_input.engable = false
        // TODO :
        this.profile_phone_carrier_input.set_engage_function(this.select_phone_carrier.bind(this))

        //////
        this.phone_carrier_list = new FloatingWall(512 / 2, 512, this.profile_phone_carrier_input.get_position().addScaledVector(this.normal, 8), this.normal, this)
        var phone_carrier_title = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'Select Phone Carrier', TYPE_TITLE, 0, 4, 0, 0)
        var pc0 = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'AT&T', TYPE_BUTTON, 0, 4, 4, 0)

        //pc0.set_engage_function(this.selected_phone_carrier('AT&T').bind(this))
        pc0.set_engage_function(function(){return this.selected_phone_carrier('AT&T').bind(this)}.bind(this))

        var pc1 = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'T-Mobile', TYPE_BUTTON, 0, 4, 5, 0)
        pc1.set_engage_function(this.selected_phone_carrier('T-Mobile').bind(this))
        this.phone_carrier_list.set_to_invisible()
        //////

        this.save_changes = this.profile_editor.add_floating_2d_text(1024, 'Save Changes', TYPE_BUTTON, 0, 2, 8, 0)

        this.interactive_objects.push(this.profile_name_label)
        this.interactive_objects.push(this.profile_name_input)
        this.interactive_objects.push(this.profile_email_label)
        this.interactive_objects.push(this.profile_email_input)
        this.interactive_objects.push(this.profile_phone_number_label)
        this.interactive_objects.push(this.profile_phone_number_input)
        this.interactive_objects.push(this.profile_phone_carrier_label)
        this.interactive_objects.push(this.profile_phone_carrier_input)
        this.interactive_objects.push(this.save_changes)
    },

    update: function() {
        this.update_interactive_objects()
    },

    key_down_event: function(event) {
        this.key_down_event_for_interactive_objects(event)
    },

    enter_world: function() {
        this.player.disengage()
        if (!PAUSED_MENU.currently_displayed) {
            this.player.enable_controls()
        }

        this.player.set_position(new THREE.Vector3(-1000, 350, 350))
        this.player.look_at(new THREE.Vector3(0.992, 0.124, -0.122))

        this.previous_world = WORLD_MANAGER.previous_world

        // Set the profile information values.

        // TODO : Grab the values from the owner entity!
        if (this.owner_entity === null) {
            this.owner_entity = ENTITY_MANAGER.get_all_entities_of_type(ENTITY_TYPE_OWNER)[0]
        }

        this.profile_name_input.update_text(this.player.owner.username)
        this.profile_email_input.update_text(this.owner_entity.get_value('owner_email'))
        this.profile_phone_number_input.update_text(this.owner_entity.get_value('owner_phone_number'))
        this.profile_phone_carrier_input.update_text(this.owner_entity.get_value('owner_phone_carrier'))
    },

    exit_world: function() {
    }
}
<commit_msg>general updating 66<commit_after>'use strict'

function SettingsWorld() {
    this.__init__()
}

// Cell phone carriers.
const CELL_PHONE_CARRIERS = {
    'None'             : '',
    'AT&T'             : 'number@txt.att.net',
    'T-Mobile'         : 'number@tmomail.net',
    'Verizon'          : 'number@vtext.com',
    'Sprint'           : 'number@pm.sprint.com',
    'Virgin Mobile'    : 'number@vmobl.com',
    'Tracfone'         : 'number@mmst5.tracfone.com',
    'Metro PCS'        : 'number@mymetropcs.com',
    'Boost Mobile'     : 'number@myboostmobile.com',
    'Cricket'          : 'number@mms.cricketwireless.net',
    'Ptel'             : 'number@ptel.com',
    'Republic Wireless': 'number@text.republicwireless.com',
    'Google Fi'        : 'number@msg.fi.google.com',
    'Suncom'           : 'number@tms.suncom.com',
    'Ting'             : 'number@message.ting.com',
    'U.S. Cellular'    : 'number@email.uscc.net',
    'Consumer Cellular': 'number@cingularme.com',
    'C-Spire'          : 'number@cspire1.com',
    'Page Plus'        : 'number@vtext.com'
}

SettingsWorld.prototype = {

    previous_world: null,

    owner_entity: null,

    select_phone_carrier: function() {
        this.phone_carrier_list.set_to_visible()
    },

    selected_phone_carrier: function(selected_phone_carrier) {
        this.phone_carrier_list.set_to_invisible()
        l('The selected phone carrier is: ')
        l(selected_phone_carrier)
    },

    __init__: function() {
        this.owner_entity = null

        // Inherit world properties.
        World.call(this, 'SettingsWorld')

        var position = new THREE.Vector3(500, 500, 700)
        this.normal = new THREE.Vector3(-.5, 0, -.85)
        this.normal.normalize()
        this.profile_editor = new FloatingWall(1024, 512 / 2, position, this.normal, this)

        var create_entity_wall_title = this.profile_editor.add_floating_2d_text(1024 / 2, 'Profile Information', TYPE_TITLE, 1024 / -4, 2, 0, 0)
        create_entity_wall_title.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_editor.add_object_to_remove_later(create_entity_wall_title)

        var label_width = 1024 / 8
        var label_offset = (1024 / -4) - label_width / 2

        this.profile_name_label = this.profile_editor.add_floating_2d_text(label_width, 'Username', TYPE_INPUT_REGULAR, label_offset, 2, 3, 0)
        this.profile_name_label.engable = false
        this.profile_name_label.set_default_color(COLOR_TEXT_CONSTANT)
        //this.profile_editor.add_object_to_remove_later(profile_name)

        this.profile_name_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 3, 0)
        //this.profile_editor.add_object_to_remove_later(profile_name_input)

        this.profile_email_label = this.profile_editor.add_floating_2d_text(label_width, 'Email', TYPE_INPUT_REGULAR, label_offset, 2, 4, 0)
        this.profile_email_label.engable = false
        this.profile_email_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_email_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 4, 0)

        this.profile_phone_number_label = this.profile_editor.add_floating_2d_text(label_width, 'Phone Number', TYPE_INPUT_REGULAR, label_offset, 2, 5, 0)
        this.profile_phone_number_label.engable = false
        this.profile_phone_number_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_phone_number_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 5, 0)

        this.profile_phone_carrier_label = this.profile_editor.add_floating_2d_text(label_width, 'Phone Carrier', TYPE_INPUT_REGULAR, label_offset, 2, 6, 0)
        this.profile_phone_carrier_label.engable = false
        this.profile_phone_carrier_label.set_default_color(COLOR_TEXT_CONSTANT)
        this.profile_phone_carrier_input = this.profile_editor.add_floating_2d_text(1024 / 2, '', TYPE_INPUT_REGULAR, 1024 / -4 + (1024 / 4) + 50, 2, 6, 0)
        this.profile_phone_carrier_input.engable = false
        // TODO :
        this.profile_phone_carrier_input.set_engage_function(this.select_phone_carrier.bind(this))

        //////
        this.phone_carrier_list = new FloatingWall(512 / 2, 512, this.profile_phone_carrier_input.get_position().addScaledVector(this.normal, 8), this.normal, this)
        var phone_carrier_title = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'Select Phone Carrier', TYPE_TITLE, 0, 4, 0, 0)
        var pc0 = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'AT&T', TYPE_BUTTON, 0, 4, 4, 0)

        //pc0.set_engage_function(this.selected_phone_carrier('AT&T').bind(this))
        pc0.set_engage_function(function(){return this.selected_phone_carrier('AT&T').bind(this)}.bind(this))

        var pc1 = this.phone_carrier_list.add_floating_2d_text(512 / 2, 'T-Mobile', TYPE_BUTTON, 0, 4, 5, 0)
        //pc1.set_engage_function(this.selected_phone_carrier('T-Mobile').bind(this))
        pc0.set_engage_function(function(){return this.selected_phone_carrier('T-Mobile').bind(this)}.bind(this))
        this.phone_carrier_list.set_to_invisible()
        //////

        this.save_changes = this.profile_editor.add_floating_2d_text(1024, 'Save Changes', TYPE_BUTTON, 0, 2, 8, 0)

        this.interactive_objects.push(this.profile_name_label)
        this.interactive_objects.push(this.profile_name_input)
        this.interactive_objects.push(this.profile_email_label)
        this.interactive_objects.push(this.profile_email_input)
        this.interactive_objects.push(this.profile_phone_number_label)
        this.interactive_objects.push(this.profile_phone_number_input)
        this.interactive_objects.push(this.profile_phone_carrier_label)
        this.interactive_objects.push(this.profile_phone_carrier_input)
        this.interactive_objects.push(this.save_changes)
    },

    update: function() {
        this.update_interactive_objects()
    },

    key_down_event: function(event) {
        this.key_down_event_for_interactive_objects(event)
    },

    enter_world: function() {
        this.player.disengage()
        if (!PAUSED_MENU.currently_displayed) {
            this.player.enable_controls()
        }

        this.player.set_position(new THREE.Vector3(-1000, 350, 350))
        this.player.look_at(new THREE.Vector3(0.992, 0.124, -0.122))

        this.previous_world = WORLD_MANAGER.previous_world

        // Set the profile information values.

        // TODO : Grab the values from the owner entity!
        if (this.owner_entity === null) {
            this.owner_entity = ENTITY_MANAGER.get_all_entities_of_type(ENTITY_TYPE_OWNER)[0]
        }

        this.profile_name_input.update_text(this.player.owner.username)
        this.profile_email_input.update_text(this.owner_entity.get_value('owner_email'))
        this.profile_phone_number_input.update_text(this.owner_entity.get_value('owner_phone_number'))
        this.profile_phone_carrier_input.update_text(this.owner_entity.get_value('owner_phone_carrier'))
    },

    exit_world: function() {
    }
}
<|endoftext|>


<commit_before>module.exports = {
  config: {
    verminal: {
      fontSize: 16,
      fontFamily: 'JetBrains Mono',
      foregroundColor: '#c9d1d9',
      backgroundColor: '#0d1117',
    },
  },
  plugins: ['hyperlinks', 'hyper-quit', 'verminal'],
  localPlugins: [],
};
<commit_msg>refactor: remove empty option in terminal config<commit_after>module.exports = {
  config: {
    verminal: {
      fontSize: 16,
      fontFamily: 'JetBrains Mono',
      foregroundColor: '#c9d1d9',
      backgroundColor: '#0d1117',
    },
  },
  plugins: ['hyperlinks', 'hyper-quit', 'verminal'],
};
<|endoftext|>


<commit_before>/**
 * The following example aims at illustrating Navitia’s journey feature.
 * It requests an itinerary from a cool spot (our headquarter in Paris)
 * to another cool spot (the Eiffel Tower, Paris).
 * Please note that the transportation data that is used for this sandbox
 * is only an example for demo purposes an does not reflect
 * the actual transportation supply on the Parisian area.
 */

$.ajax({
  type: 'GET',
  url: 'https://api.navitia.io/v1/journeys?from=2.3749036;48.8467927&to=2.2922926;48.8583736',
  dataType: 'json',
  headers: {
    'Authorization': 'Basic ' + btoa('a61f4cd8-3007-4557-9f4c-214969369cca')
  },
  success: function(result) {
    displayJourney(result.journeys[0]);
    $("#raw-result").html(pretty.json.prettyPrint(result));
  },
  error: function(xhr, textStatus, errorThrown) {
    $("#raw-result").html('Error: ' + textStatus + ' ' + errorThrown);
  }
});

function displayJourney(journey) {
  var $tbody = $('tbody');

  $.each(journey.sections, function(index, section) {
    var $tr = $('
');

    $tr.append($('').html(index));
    $tr.append($('').html(formatHour(section.departure_date_time)));
    $tr.append($('').html(formatHour(section.arrival_date_time)));
    $tr.append($('').html(section.from && section.from.name));
    $tr.append($('').html(section.to && section.to.name));
    $tr.append($('').html(section.mode));
    $tr.append($('').html(section.type));
    $tr.append($('').html(section.display_informations && section.display_informations.physical_mode));
    $tr.append($('').html(section.display_informations && section.display_informations.code));

    $tbody.append($tr);
  });
}

function formatHour(navitiaDate) {
  return navitiaDate.substr(9).match(/.{2}/g).join(':');
}

if (!pretty)
  var pretty = {};

pretty.json = {
  replacer: function(match, pIndent, pKey, pVal, pEnd) {
    var key = '';
    var val = '';
    var str = '';
    var r = pIndent || '';
    if (pKey)
      r = r + key + pKey.replace(/[": ]/g, '') + ': ';
    if (pVal)
      r = r + (pVal[0] == '"' ? str : val) + pVal + '';
    return r + (pEnd || '');
  },
  prettyPrint: function(obj) {
    var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
    return JSON.stringify(obj, null, 3)
      .replace(/&/g, '&').replace(/\\"/g, '"')
      .replace(/</g, '<').replace(/>/g, '>')
      .replace(jsonLine, pretty.json.replacer);
  }
};
<commit_msg>use sandbox data<commit_after>/**
 * The following example aims at illustrating Navitia’s journey feature.
 * It requests an itinerary from a cool spot (our headquarter in Paris)
 * to another cool spot (the Eiffel Tower, Paris).
 * Please note that the transportation data that is used for this sandbox
 * is only an example for demo purposes an does not reflect
 * the actual transportation supply on the Parisian area.
 */

$.ajax({
  type: 'GET',
  url: 'https://api.navitia.io/v1/coverage/sandbox/journeys?from=2.3749036;48.8467927&to=2.2922926;48.8583736',
  dataType: 'json',
  headers: {
    Authorization: 'Basic ' + btoa('a61f4cd8-3007-4557-9f4c-214969369cca')
  },
  success: function(result) {
    displayJourney(result.journeys[0]);
    $("#raw-result").html(pretty.json.prettyPrint(result));
  },
  error: function(xhr, textStatus, errorThrown) {
    $("#raw-result").html('Error: ' + textStatus + ' ' + errorThrown);
  }
});

function displayJourney(journey) {
  var $tbody = $('tbody');

  $.each(journey.sections, function(index, section) {
    var $tr = $('
');

    $tr.append($('').html(index));
    $tr.append($('').html(formatHour(section.departure_date_time)));
    $tr.append($('').html(formatHour(section.arrival_date_time)));
    $tr.append($('').html(section.from && section.from.name));
    $tr.append($('').html(section.to && section.to.name));
    $tr.append($('').html(section.mode));
    $tr.append($('').html(section.type));
    $tr.append($('').html(section.display_informations && section.display_informations.physical_mode));
    $tr.append($('').html(section.display_informations && section.display_informations.code));

    $tbody.append($tr);
  });
}

function formatHour(navitiaDate) {
  return navitiaDate.substr(9).match(/.{2}/g).join(':');
}

if (!pretty)
  var pretty = {};

pretty.json = {
  replacer: function(match, pIndent, pKey, pVal, pEnd) {
    var key = '';
    var val = '';
    var str = '';
    var r = pIndent || '';
    if (pKey)
      r = r + key + pKey.replace(/[": ]/g, '') + ': ';
    if (pVal)
      r = r + (pVal[0] == '"' ? str : val) + pVal + '';
    return r + (pEnd || '');
  },
  prettyPrint: function(obj) {
    var jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
    return JSON.stringify(obj, null, 3)
      .replace(/&/g, '&').replace(/\\"/g, '"')
      .replace(/</g, '<').replace(/>/g, '>')
      .replace(jsonLine, pretty.json.replacer);
  }
};
<|endoftext|>


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

'use strict';

module.exports = {
  opts: {
    readme: './README.md',
    package: './package.json',
    template: './node_modules/jsdoc-baseline',
    recurse: true,
    verbose: true,
    destination: './docs/'
  },
  plugins: [
    'plugins/markdown'
  ],
  source: {
    excludePattern: '(^|\\/|\\\\)[._]',
    include: [
      'src'
    ],
    includePattern: '\\.js$'
  },
  templates: {
    copyright: 'Copyright 2018 Google, LLC.',
    includeDate: false,
    sourceFiles: false,
    systemName: 'teeny-request',
    theme: 'lumen'
  },
  markdown: {
    idInHeadings: true
  }
};
<commit_msg>docs: use the jsdoc-fresh theme (#58)<commit_after>/*!
 * Copyright 2018 Google LLC. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

module.exports = {
  opts: {
    readme: './README.md',
    package: './package.json',
    template: './node_modules/jsdoc-fresh',
    recurse: true,
    verbose: true,
    destination: './docs/'
  },
  plugins: [
    'plugins/markdown'
  ],
  source: {
    excludePattern: '(^|\\/|\\\\)[._]',
    include: [
      'src'
    ],
    includePattern: '\\.js$'
  },
  templates: {
    copyright: 'Copyright 2018 Google, LLC.',
    includeDate: false,
    sourceFiles: false,
    systemName: 'teeny-request',
    theme: 'lumen'
  },
  markdown: {
    idInHeadings: true
  }
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';

export default class MentionSuggestionsPortal extends Component {

  componentDidMount() {
    this.props.store.register(this.props.offsetKey);
    this.updatePortalClientRect(this.props);

    // trigger a re-render so the MentionSuggestions becomes active
    this.props.setEditorState(this.props.getEditorState());
  }

  componentWillReceiveProps(nextProps) {
    this.updatePortalClientRect(nextProps);
  }

  componentWillUnmount() {
    this.props.store.unregister(this.props.offsetKey);
  }

  updatePortalClientRect(props) {
    this.props.store.updatePortalClientRect(
      props.offsetKey,
      () => (
        this.searchPortal.getBoundingClientRect()
      ),
    );
  }

  render() {
    return (
      <span
        className={this.key}
        ref={(element) => { this.searchPortal = element; }}
      >
        {this.props.children}
      </span>
    );
  }
}
<commit_msg>add info comment why this must be componentDidMount<commit_after>import React, { Component } from 'react';

export default class MentionSuggestionsPortal extends Component {

  // When inputting Japanese characters (or any complex alphabet which requires
  // hitting enter to commit the characters), that action was causing a race
  // condition when we used componentWillMount. By using componentDidMount
  // instead of componentWillMount, the component will unmount unregister and
  // then properly mount and register after. Prior to this change,
  // componentWillMount would not fire after componentWillUnmount even though it
  // was still in the DOM, so it wasn't re-registering the offsetkey.
  componentDidMount() {
    this.props.store.register(this.props.offsetKey);
    this.updatePortalClientRect(this.props);

    // trigger a re-render so the MentionSuggestions becomes active
    this.props.setEditorState(this.props.getEditorState());
  }

  componentWillReceiveProps(nextProps) {
    this.updatePortalClientRect(nextProps);
  }

  componentWillUnmount() {
    this.props.store.unregister(this.props.offsetKey);
  }

  updatePortalClientRect(props) {
    this.props.store.updatePortalClientRect(
      props.offsetKey,
      () => (
        this.searchPortal.getBoundingClientRect()
      ),
    );
  }

  render() {
    return (
      <span
        className={this.key}
        ref={(element) => { this.searchPortal = element; }}
      >
        {this.props.children}
      </span>
    );
  }
}
<|endoftext|>


<commit_before>'use strict';

const dbDsl = require('dumonda-me-server-test-util').dbDSL;
const db = require('dumonda-me-server-test-util').db;
const eMail = require('dumonda-me-server-lib').eMail;
const sinon = require('sinon');
const testee = requireSrc('notifications');

describe('Send email when multiple unread notification exist', function () {

    let stubSendEMail, sandbox;

    beforeEach(async function () {
        await dbDsl.init(6);
        sandbox = sinon.sandbox.create();
        stubSendEMail = sandbox.stub(eMail, 'sendEMail');
        stubSendEMail.resolves({});

        dbDsl.createQuestion('1', {
            creatorId: '2', question: 'Das ist eine FragöÖÄäÜü', description: 'description', topics: ['Spiritual'],
            language: 'de'
        });
        dbDsl.createTextAnswer('5', {
            creatorId: '2', questionId:'1', answer: 'Answer'
        });
        dbDsl.createNote('50', {answerId: '5', creatorId: '2', created: 555});

        dbDsl.notificationCreateNote('100', {questionId: '1', answerId: '5', noteId: '50', created: 678});
        dbDsl.notificationUserAddedToTrustCircle('101', {
            userId: '2',
            trustCircleUsers: [{userId: '3', created: 555}, {userId: '4', created: 444}], created: 600
        });
        dbDsl.notificationCreateAnswer('102', {questionId: '1', answerId: '5', created: 678});

    });

    afterEach(function () {
        sandbox.restore();
    });

    it('Send unread notification', async function () {
        await dbDsl.sendToDb();

        await testee.sendUnreadNotifications();

        stubSendEMail.calledWith("notification", {
            numberOfNotifications: 3,
            unsubscribeLink: `${process.env.DUMONDA_ME_DOMAIN}unsubscribe/notifications/user2@irgendwo.ch`
        }, 'de', 'user2@irgendwo.ch').should.be.true;

        let notification = await db.cypher().match("(notification:Notification:EmailSent)")
            .return(`notification`).end().send();
        notification.length.should.equals(3);
    });
});
<commit_msg>Renamed Text answer to Default.<commit_after>'use strict';

const dbDsl = require('dumonda-me-server-test-util').dbDSL;
const db = require('dumonda-me-server-test-util').db;
const eMail = require('dumonda-me-server-lib').eMail;
const sinon = require('sinon');
const testee = requireSrc('notifications');

describe('Send email when multiple unread notification exist', function () {

    let stubSendEMail, sandbox;

    beforeEach(async function () {
        await dbDsl.init(6);
        sandbox = sinon.sandbox.create();
        stubSendEMail = sandbox.stub(eMail, 'sendEMail');
        stubSendEMail.resolves({});

        dbDsl.createQuestion('1', {
            creatorId: '2', question: 'Das ist eine FragöÖÄäÜü', description: 'description', topics: ['Spiritual'],
            language: 'de'
        });
        dbDsl.createDefaultAnswer('5', {
            creatorId: '2', questionId:'1', answer: 'Answer'
        });
        dbDsl.createNote('50', {answerId: '5', creatorId: '2', created: 555});

        dbDsl.notificationCreateNote('100', {questionId: '1', answerId: '5', noteId: '50', created: 678});
        dbDsl.notificationUserAddedToTrustCircle('101', {
            userId: '2',
            trustCircleUsers: [{userId: '3', created: 555}, {userId: '4', created: 444}], created: 600
        });
        dbDsl.notificationCreateAnswer('102', {questionId: '1', answerId: '5', created: 678});

    });

    afterEach(function () {
        sandbox.restore();
    });

    it('Send unread notification', async function () {
        await dbDsl.sendToDb();

        await testee.sendUnreadNotifications();

        stubSendEMail.calledWith("notification", {
            numberOfNotifications: 3,
            unsubscribeLink: `${process.env.DUMONDA_ME_DOMAIN}unsubscribe/notifications/user2@irgendwo.ch`
        }, 'de', 'user2@irgendwo.ch').should.be.true;

        let notification = await db.cypher().match("(notification:Notification:EmailSent)")
            .return(`notification`).end().send();
        notification.length.should.equals(3);
    });
});
<|endoftext|>


<commit_before>/**
 * Created by Bryan Henderson on 4/16/2014.
 */
var Editors = angular.module("Editors",
    [
        'ngResource',
        'ui.router',
        'ui.bootstrap',
        'ngTable',
        'xeditable',
        'ui.tree',
        'ui.sortable',
        'ngAnimate',
        'textAngular',
        'restangular',
        'angularUtils.directives.uiBreadcrumbs',
        'EscreeningDashboardApp.services.battery',
        'EscreeningDashboardApp.services.survey',
        'EscreeningDashboardApp.services.surveypage',
        'EscreeningDashboardApp.services.surveysection',
        'EscreeningDashboardApp.services.question',
        'EscreeningDashboardApp.services.template',
        'EscreeningDashboardApp.services.assessmentVariable',
        'EscreeningDashboardApp.services.question',
        'EscreeningDashboardApp.filters.messages',
        'EscreeningDashboardApp.filters.freemarkerWhiteSpace',
        'EscreeningDashboardApp.filters.limitToWithEllipsis'
    ]);

/**
 * A generic confirmation for risky actions.
 * Usage: Add attributes: ng-really-message="Are you sure"? ng-really-click="takeAction()" function
 */
Editors.directive('ngReallyClick', [function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                var message = attrs.ngReallyMessage;
                if (message && confirm(message)) {
                    scope.$apply(attrs.ngReallyClick);
                }
            });
        }
    };
}]);

Editors.config(function(RestangularProvider, $provide) {
    RestangularProvider.setBaseUrl('/escreeningdashboard/dashboard');
    RestangularProvider.setRequestSuffix('.json');

	$provide.decorator('taOptions', ['taRegisterTool', '$delegate', function(taRegisterTool, $delegate){
		// $delegate is the taOptions we are decorating
		// register the tool with textAngular
		taRegisterTool('addVariable', {
			iconclass: "fa fa-plus",
			buttonText: 'Add Variable',
			action: function(){
				this.$editor().wrapSelection('forecolor', 'red');
			}
		});
		// add the button to the default toolbar definition
		$delegate.toolbar[4] = ['addVariable'];
		return $delegate;
	}]);
});

Editors.run(function(editableOptions) {
    editableOptions.theme = 'bs3';
});

Editors.run(['$rootScope', '$state', '$stateParams', '$modal', function ($rootScope,   $state,   $stateParams,  $modal) {
    // It's very handy to add references to $state and $stateParams to the $rootScope
    // so that you can access them from any scope within your applications.For example,
    //
 will set the

    // to active whenever 'assessments.list' or one of its descendents is active.
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;

}]);
Editors.value('MessageHandler', new BytePushers.models.MessageHandler());
Editors.value('TemplateType', new EScreeningDashboardApp.models.TemplateType());
<commit_msg>#660 - Removed unnecessary Restangular configuration; as I have moved to the Restangular Service.<commit_after>/**
 * Created by Bryan Henderson on 4/16/2014.
 */
var Editors = angular.module("Editors",
    [
        'ngResource',
        'ui.router',
        'ui.bootstrap',
        'ngTable',
        'xeditable',
        'ui.tree',
        'ui.sortable',
        'ngAnimate',
        'textAngular',
        'restangular',
        'angularUtils.directives.uiBreadcrumbs',
        'EscreeningDashboardApp.services.battery',
        'EscreeningDashboardApp.services.survey',
        'EscreeningDashboardApp.services.surveypage',
        'EscreeningDashboardApp.services.surveysection',
        'EscreeningDashboardApp.services.question',
        'EscreeningDashboardApp.services.template',
        'EscreeningDashboardApp.services.assessmentVariable',
        'EscreeningDashboardApp.services.question',
        'EscreeningDashboardApp.filters.messages',
        'EscreeningDashboardApp.filters.freemarkerWhiteSpace',
        'EscreeningDashboardApp.filters.limitToWithEllipsis'
    ]);

/**
 * A generic confirmation for risky actions.
 * Usage: Add attributes: ng-really-message="Are you sure"? ng-really-click="takeAction()" function
 */
Editors.directive('ngReallyClick', [function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                var message = attrs.ngReallyMessage;
                if (message && confirm(message)) {
                    scope.$apply(attrs.ngReallyClick);
                }
            });
        }
    };
}]);

Editors.config(function(RestangularProvider, $provide) {
    $provide.decorator('taOptions', ['taRegisterTool', '$delegate', function(taRegisterTool, $delegate){
		// $delegate is the taOptions we are decorating
		// register the tool with textAngular
		taRegisterTool('addVariable', {
			iconclass: "fa fa-plus",
			buttonText: 'Add Variable',
			action: function(){
				this.$editor().wrapSelection('forecolor', 'red');
			}
		});
		// add the button to the default toolbar definition
		$delegate.toolbar[4] = ['addVariable'];
		return $delegate;
	}]);
});

Editors.run(function(editableOptions) {
    editableOptions.theme = 'bs3';
});

Editors.run(['$rootScope', '$state', '$stateParams', '$modal', function ($rootScope,   $state,   $stateParams,  $modal) {
    // It's very handy to add references to $state and $stateParams to the $rootScope
    // so that you can access them from any scope within your applications.For example,
    //
 will set the

    // to active whenever 'assessments.list' or one of its descendents is active.
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;

}]);
Editors.value('MessageHandler', new BytePushers.models.MessageHandler());
Editors.value('TemplateType', new EScreeningDashboardApp.models.TemplateType());
<|endoftext|>