<commit_before>'use strict';
// gulp
var gulp = require('gulp');
var paths = gulp.paths;
var options = gulp.options;
// plugins
var $ = require('gulp-load-plugins')();
// modules
var wiredep = require('wiredep');
var mainBowerFiles = require('main-bower-files');

// inject app/**/*.js, bower components, css into index.html
// inject environment variables into config.js constant
gulp.task('inject-all', ['styles', 'wiredep', 'bower-fonts', 'environment', 'build-vars'], function () {

  return gulp.src('app/index.html')
    .pipe(
      $.inject( // app/**/*.js files
        gulp.src(paths.jsFiles)
          .pipe($.plumber()) // use plumber so watch can start despite js errors
          .pipe($.naturalSort())
          .pipe($.angularFilesort()),
        {relative: true}))
    .pipe(
      $.inject( // inject compiled css
        gulp.src('.tmp/*/styles/*.css', {read: false}),
        {
          ignorePath: '../.tmp',
          relative: true,
        }))
    .pipe(gulp.dest('app'));
});

// build styles to tmp
gulp.task('styles', ['clean'], function () {

  // compile css starting from each module's scss
  return gulp.src('app/*/styles/!(_)*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass.sync().on('error', $.sass.logError))
    .pipe($.autoprefixer({ browsers: ['last 2 versions'], remove: false}))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('.tmp/'));
});

// inject bower components into index.html
gulp.task('wiredep', function () {

  return gulp.src('app/index.html')
<% if (answers.ionicCss) { -%>
    // we're not excluding the ionic css here
    .pipe(wiredep.stream())
<% } else { -%>
    // exclude ionic scss since we're using ionic sass
    .pipe(wiredep.stream({exclude: ['bower_components/ionic/release/css']}))
<% } -%>
    .pipe(gulp.dest('app/'));
});

// copy bower fonts
<% if (answers.ionicCss) { -%>
gulp.task('bower-fonts', ['clean'], function () {
  // to do www/fonts (ionic css requires it to be in this folder)
  var DEST = 'www/fonts';
  var fontFiles = mainBowerFiles({filter: /\.(eot|otf|svg|ttf|woff|woff2)$/i});
<% } else { -%>
gulp.task('bower-fonts', function () {
  // to app/main/assets/fonts (path can be set in app/main/styles/<module>.scss)
  var DEST = 'app/main/assets/fonts';
  var fontFiles = mainBowerFiles({filter: /\.(eot|otf|svg|ttf|woff|woff2)$/i})
    .concat('app/main/assets/fonts/**/*');
<% } -%>

  return gulp.src(fontFiles)
    .pipe($.changed(DEST))
    .pipe(gulp.dest(DEST));
});

/**
 * transforms object into a string format that is ready for injection at indentation 4
 * @param  {Object} obj Object with values to inject
 * @return {String}     properly formatted string
 */
var injectFormat = function (obj) {
  // indentation of 2
  obj = JSON.stringify(obj, null, 2);
  // replace all doublequotes with singlequotes
  obj = obj.replace(/\"/g, '\'');
  // remove first and last line curly braces
  obj = obj.replace(/^\{\n/, '').replace(/\n\}$/, '');
  // remove indentation of first line
  obj = obj.replace(/^( ){2}/, '');
  // insert padding for all remaining lines
  obj = obj.replace(/\n( ){2}/g, '\n    ');

  return obj;
};

gulp.task('environment', function () {
  return gulp.src('app/*/constants/*config-const.js')
    .pipe(
      $.inject(
        gulp.src('app/main/constants/env-' + options.env + '.json'),
        {
          starttag: '/*inject-env*/',
          endtag: '/*endinject*/',
          transform: function (filePath, file) {
            var json;
            try {
              json = JSON.parse(file.contents.toString('utf8'));
            }
            catch (e) {
              console.log(e);
            }

            if (json) {
              json = injectFormat(json);
            }
            return json;
          }
        }))
    .pipe(gulp.dest('app/'));
});

gulp.task('build-vars', ['environment'], function () {
  return gulp.src('app/*/constants/*config-const.js')
    .pipe(
      $.inject(
        gulp.src(''),
        {
          starttag: '/*inject-build*/',
          endtag: '/*endinject*/',
          transform: function () {
            var obj = {};
            var buildVars = options.buildVars;

            if (buildVars) {
              // loop over build variables
              var variables = buildVars.split(',');
              for (var i = 0, variable; ((variable = variables[i])); i++) {
                var splits = variable.split(':');
                // add key and value to object
                obj[splits[0]] = splits[1];
              }
              return injectFormat(obj);
            }
            else {
              return;
            }
          }
        }))
    .pipe(gulp.dest('app/'));
});
<commit_msg>fixes #256: inconsistent injection order of css files<commit_after>'use strict';
// gulp
var gulp = require('gulp');
var paths = gulp.paths;
var options = gulp.options;
// plugins
var $ = require('gulp-load-plugins')();
// modules
var wiredep = require('wiredep');
var mainBowerFiles = require('main-bower-files');

// inject app/**/*.js, bower components, css into index.html
// inject environment variables into config.js constant
gulp.task('inject-all', ['styles', 'wiredep', 'bower-fonts', 'environment', 'build-vars'], function () {

  return gulp.src('app/index.html')
    .pipe(
      $.inject( // app/**/*.js files
        gulp.src(paths.jsFiles)
          .pipe($.plumber()) // use plumber so watch can start despite js errors
          .pipe($.naturalSort())
          .pipe($.angularFilesort()),
        {relative: true}))
    .pipe(
      $.inject( // inject compiled css
        gulp.src('.tmp/*/styles/*.css', {read: false})
          .pipe($.naturalSort()),
        {
          ignorePath: '../.tmp',
          relative: true,
        }))
    .pipe(gulp.dest('app'));
});

// build styles to tmp
gulp.task('styles', ['clean'], function () {

  // compile css starting from each module's scss
  return gulp.src('app/*/styles/!(_)*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass.sync().on('error', $.sass.logError))
    .pipe($.autoprefixer({ browsers: ['last 2 versions'], remove: false}))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('.tmp/'));
});

// inject bower components into index.html
gulp.task('wiredep', function () {

  return gulp.src('app/index.html')
<% if (answers.ionicCss) { -%>
    // we're not excluding the ionic css here
    .pipe(wiredep.stream())
<% } else { -%>
    // exclude ionic scss since we're using ionic sass
    .pipe(wiredep.stream({exclude: ['bower_components/ionic/release/css']}))
<% } -%>
    .pipe(gulp.dest('app/'));
});

// copy bower fonts
<% if (answers.ionicCss) { -%>
gulp.task('bower-fonts', ['clean'], function () {
  // to do www/fonts (ionic css requires it to be in this folder)
  var DEST = 'www/fonts';
  var fontFiles = mainBowerFiles({filter: /\.(eot|otf|svg|ttf|woff|woff2)$/i});
<% } else { -%>
gulp.task('bower-fonts', function () {
  // to app/main/assets/fonts (path can be set in app/main/styles/<module>.scss)
  var DEST = 'app/main/assets/fonts';
  var fontFiles = mainBowerFiles({filter: /\.(eot|otf|svg|ttf|woff|woff2)$/i})
    .concat('app/main/assets/fonts/**/*');
<% } -%>

  return gulp.src(fontFiles)
    .pipe($.changed(DEST))
    .pipe(gulp.dest(DEST));
});

/**
 * transforms object into a string format that is ready for injection at indentation 4
 * @param  {Object} obj Object with values to inject
 * @return {String}     properly formatted string
 */
var injectFormat = function (obj) {
  // indentation of 2
  obj = JSON.stringify(obj, null, 2);
  // replace all doublequotes with singlequotes
  obj = obj.replace(/\"/g, '\'');
  // remove first and last line curly braces
  obj = obj.replace(/^\{\n/, '').replace(/\n\}$/, '');
  // remove indentation of first line
  obj = obj.replace(/^( ){2}/, '');
  // insert padding for all remaining lines
  obj = obj.replace(/\n( ){2}/g, '\n    ');

  return obj;
};

gulp.task('environment', function () {
  return gulp.src('app/*/constants/*config-const.js')
    .pipe(
      $.inject(
        gulp.src('app/main/constants/env-' + options.env + '.json'),
        {
          starttag: '/*inject-env*/',
          endtag: '/*endinject*/',
          transform: function (filePath, file) {
            var json;
            try {
              json = JSON.parse(file.contents.toString('utf8'));
            }
            catch (e) {
              console.log(e);
            }

            if (json) {
              json = injectFormat(json);
            }
            return json;
          }
        }))
    .pipe(gulp.dest('app/'));
});

gulp.task('build-vars', ['environment'], function () {
  return gulp.src('app/*/constants/*config-const.js')
    .pipe(
      $.inject(
        gulp.src(''),
        {
          starttag: '/*inject-build*/',
          endtag: '/*endinject*/',
          transform: function () {
            var obj = {};
            var buildVars = options.buildVars;

            if (buildVars) {
              // loop over build variables
              var variables = buildVars.split(',');
              for (var i = 0, variable; ((variable = variables[i])); i++) {
                var splits = variable.split(':');
                // add key and value to object
                obj[splits[0]] = splits[1];
              }
              return injectFormat(obj);
            }
            else {
              return;
            }
          }
        }))
    .pipe(gulp.dest('app/'));
});
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.streamSingle = exports.current = undefined;

var _weather = require('../service/weather');

var weather = _interopRequireWildcard(_weather);

var _config = require('../config');

var _config2 = _interopRequireDefault(_config);

var _redis = require('../redis');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

const STREAM_CLIENTS_KEY = (0, _config2.default)('NAME_VERSION', true) + '_stream_clients_weather';

const current = exports.current = (() => {
    var _ref = _asyncToGenerator(function* (ctx) {
        try {
            ctx.body = yield weather.current();
        } catch (boom) {
            ctx.body = boom.output.payload;
            ctx.status = boom.output.statusCode;
        }
    });

    return function current(_x) {
        return _ref.apply(this, arguments);
    };
})();

const streamSingle = exports.streamSingle = (() => {
    var _ref2 = _asyncToGenerator(function* ({ emit, disconnect }) {
        console.log('hellow');
        _redis.redis.incr(STREAM_CLIENTS_KEY);
        var res = weather.fireHose(function (data) {
            emit(data);
        });

        disconnect(function () {
            _redis.redis.decr(STREAM_CLIENTS_KEY);
            res.off();
        });
    });

    return function streamSingle(_x2) {
        return _ref2.apply(this, arguments);
    };
})();<commit_msg>update build<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.streamSingle = exports.current = undefined;

var _weather = require('../service/weather');

var weather = _interopRequireWildcard(_weather);

var _config = require('../config');

var _config2 = _interopRequireDefault(_config);

var _redis = require('../redis');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

const STREAM_CLIENTS_KEY = (0, _config2.default)('NAME_VERSION', true) + '_stream_clients_weather';

const current = exports.current = (() => {
    var _ref = _asyncToGenerator(function* (ctx) {
        try {
            ctx.body = yield weather.current();
        } catch (boom) {
            ctx.body = boom.output.payload;
            ctx.status = boom.output.statusCode;
        }
    });

    return function current(_x) {
        return _ref.apply(this, arguments);
    };
})();

const streamSingle = exports.streamSingle = (() => {
    var _ref2 = _asyncToGenerator(function* ({ emit, disconnect }) {
        _redis.redis.incr(STREAM_CLIENTS_KEY);
        var res = weather.fireHose(function (data) {
            emit(data);
        });

        disconnect(function () {
            _redis.redis.decr(STREAM_CLIENTS_KEY);
            res.off();
        });
    });

    return function streamSingle(_x2) {
        return _ref2.apply(this, arguments);
    };
})();<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

/**
 * This event denotes the beginning of a series of tracking events.
 *
 * @module PointerGestures
 * @submodule Events
 * @class trackstart
 */
/**
 * Pixels moved in the x direction since trackstart.
 * @type Number
 * @property dx
 */
/**
 * Pixes moved in the y direction since trackstart.
 * @type Number
 * @property dy
 */
/**
 * Pixels moved in the x direction since the last track.
 * @type Number
 * @property ddx
 */
/**
 * Pixles moved in the y direction since the last track.
 * @type Number
 * @property ddy
 */
/**
 * The clientX position of the track gesture.
 * @type Number
 * @property clientX
 */
/**
 * The clientY position of the track gesture.
 * @type Number
 * @property clientY
 */
/**
 * The pageX position of the track gesture.
 * @type Number
 * @property pageX
 */
/**
 * The pageY position of the track gesture.
 * @type Number
 * @property pageY
 */
/**
 * The screenX position of the track gesture.
 * @type Number
 * @property screenX
 */
/**
 * The screenY position of the track gesture.
 * @type Number
 * @property screenY
 */
/**
 * The last x axis direction of the pointer.
 * @type Number
 * @property xDirection
 */
/**
 * The last y axis direction of the pointer.
 * @type Number
 * @property yDirection
 */
/**
 * A shared object between all tracking events.
 * @type Object
 * @property trackInfo
 */
/**
 * The type of pointer that make the track gesture.
 * @type String
 * @property pointerType
 */
/**
 *
 * This event fires for all pointer movement being tracked.
 *
 * @class track
 * @extends trackstart
 */
/**
 * This event fires when the pointer is no longer being tracked.
 *
 * @class trackend
 * @extends trackstart
 */

 (function(scope) {
   var dispatcher = scope.dispatcher;
   var pointermap = new scope.PointerMap;
   var track = {
     events: [
       'pointerdown',
       'pointermove',
       'pointerup',
       'pointercancel'
     ],
     WIGGLE_THRESHOLD: 4,
     clampDir: function(inDelta) {
       return inDelta > 0 ? 1 : -1;
     },
     calcPositionDelta: function(inA, inB) {
       var x = 0, y = 0;
       if (inA && inB) {
         x = inB.pageX - inA.pageX;
         y = inB.pageY - inA.pageY;
       }
       return {x: x, y: y};
     },
     fireTrack: function(inType, inEvent, inTrackingData) {
       var t = inTrackingData;
       var d = this.calcPositionDelta(t.downEvent, inEvent);
       var dd = this.calcPositionDelta(t.lastMoveEvent, inEvent);
       if (dd.x) {
         t.xDirection = this.clampDir(dd.x);
       }
       if (dd.y) {
         t.yDirection = this.clampDir(dd.y);
       }
       var trackData = {
         dx: d.x,
         dy: d.y,
         ddx: dd.x,
         ddy: dd.y,
         clientX: inEvent.clientX,
         clientY: inEvent.clientY,
         pageX: inEvent.pageX,
         pageY: inEvent.pageY,
         screenX: inEvent.screenX,
         screenY: inEvent.screenY,
         xDirection: t.xDirection,
         yDirection: t.yDirection,
         trackInfo: t.trackInfo,
         pointerType: inEvent.pointerType
       };
       if (inType === 'trackend') {
         // TODO(dfreedman): this will leak shadowdom targets, replace with a
         // more sophisticated mechanism
         trackData._releaseTarget = inEvent.target;
       }
       var e = dispatcher.makeEvent(inType, trackData);
       t.lastMoveEvent = inEvent;
       dispatcher.dispatchEvent(e, t.downTarget);
     },
     pointerdown: function(inEvent) {
       if (inEvent.isPrimary && (inEvent.pointerType === 'mouse' ? inEvent.buttons === 1 : true)) {
         var p = {
           downEvent: inEvent,
           downTarget: inEvent.target,
           trackInfo: {},
           lastMoveEvent: null,
           xDirection: 0,
           yDirection: 0,
           tracking: false
         };
         pointermap.set(inEvent.pointerId, p);
       }
     },
     pointermove: function(inEvent) {
       var p = pointermap.get(inEvent.pointerId);
       if (p) {
         if (!p.tracking) {
           var d = this.calcPositionDelta(p.downEvent, inEvent);
           var move = d.x * d.x + d.y * d.y;
           // start tracking only if finger moves more than WIGGLE_THRESHOLD
           if (move > this.WIGGLE_THRESHOLD) {
             p.tracking = true;
             this.fireTrack('trackstart', p.downEvent, p);
             this.fireTrack('track', inEvent, p);
           }
         } else {
           this.fireTrack('track', inEvent, p);
         }
       }
     },
     pointerup: function(inEvent) {
       var p = pointermap.get(inEvent.pointerId);
       if (p) {
         if (p.tracking) {
           this.fireTrack('trackend', inEvent, p);
         }
         pointermap.delete(inEvent.pointerId);
       }
     },
     pointercancel: function(inEvent) {
       this.pointerup(inEvent);
     }
   };
   dispatcher.registerRecognizer('track', track);
 })(window.PointerGestures);
<commit_msg>Add the element under the pointer to track events as relatedTarget<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

/**
 * This event denotes the beginning of a series of tracking events.
 *
 * @module PointerGestures
 * @submodule Events
 * @class trackstart
 */
/**
 * Pixels moved in the x direction since trackstart.
 * @type Number
 * @property dx
 */
/**
 * Pixes moved in the y direction since trackstart.
 * @type Number
 * @property dy
 */
/**
 * Pixels moved in the x direction since the last track.
 * @type Number
 * @property ddx
 */
/**
 * Pixles moved in the y direction since the last track.
 * @type Number
 * @property ddy
 */
/**
 * The clientX position of the track gesture.
 * @type Number
 * @property clientX
 */
/**
 * The clientY position of the track gesture.
 * @type Number
 * @property clientY
 */
/**
 * The pageX position of the track gesture.
 * @type Number
 * @property pageX
 */
/**
 * The pageY position of the track gesture.
 * @type Number
 * @property pageY
 */
/**
 * The screenX position of the track gesture.
 * @type Number
 * @property screenX
 */
/**
 * The screenY position of the track gesture.
 * @type Number
 * @property screenY
 */
/**
 * The last x axis direction of the pointer.
 * @type Number
 * @property xDirection
 */
/**
 * The last y axis direction of the pointer.
 * @type Number
 * @property yDirection
 */
/**
 * A shared object between all tracking events.
 * @type Object
 * @property trackInfo
 */
/**
 * The element currently under the pointer.
 * @type Element
 * @property relatedTarget
 */
/**
 * The type of pointer that make the track gesture.
 * @type String
 * @property pointerType
 */
/**
 *
 * This event fires for all pointer movement being tracked.
 *
 * @class track
 * @extends trackstart
 */
/**
 * This event fires when the pointer is no longer being tracked.
 *
 * @class trackend
 * @extends trackstart
 */

 (function(scope) {
   var dispatcher = scope.dispatcher;
   var pointermap = new scope.PointerMap();
   var track = {
     events: [
       'pointerdown',
       'pointermove',
       'pointerup',
       'pointercancel'
     ],
     WIGGLE_THRESHOLD: 4,
     clampDir: function(inDelta) {
       return inDelta > 0 ? 1 : -1;
     },
     calcPositionDelta: function(inA, inB) {
       var x = 0, y = 0;
       if (inA && inB) {
         x = inB.pageX - inA.pageX;
         y = inB.pageY - inA.pageY;
       }
       return {x: x, y: y};
     },
     fireTrack: function(inType, inEvent, inTrackingData) {
       var t = inTrackingData;
       var d = this.calcPositionDelta(t.downEvent, inEvent);
       var dd = this.calcPositionDelta(t.lastMoveEvent, inEvent);
       if (dd.x) {
         t.xDirection = this.clampDir(dd.x);
       }
       if (dd.y) {
         t.yDirection = this.clampDir(dd.y);
       }
       var trackData = {
         dx: d.x,
         dy: d.y,
         ddx: dd.x,
         ddy: dd.y,
         clientX: inEvent.clientX,
         clientY: inEvent.clientY,
         pageX: inEvent.pageX,
         pageY: inEvent.pageY,
         screenX: inEvent.screenX,
         screenY: inEvent.screenY,
         xDirection: t.xDirection,
         yDirection: t.yDirection,
         trackInfo: t.trackInfo,
         relatedTarget: inEvent.target,
         pointerType: inEvent.pointerType
       };
       var e = dispatcher.makeEvent(inType, trackData);
       t.lastMoveEvent = inEvent;
       dispatcher.dispatchEvent(e, t.downTarget);
     },
     pointerdown: function(inEvent) {
       if (inEvent.isPrimary && (inEvent.pointerType === 'mouse' ? inEvent.buttons === 1 : true)) {
         var p = {
           downEvent: inEvent,
           downTarget: inEvent.target,
           trackInfo: {},
           lastMoveEvent: null,
           xDirection: 0,
           yDirection: 0,
           tracking: false
         };
         pointermap.set(inEvent.pointerId, p);
       }
     },
     pointermove: function(inEvent) {
       var p = pointermap.get(inEvent.pointerId);
       if (p) {
         if (!p.tracking) {
           var d = this.calcPositionDelta(p.downEvent, inEvent);
           var move = d.x * d.x + d.y * d.y;
           // start tracking only if finger moves more than WIGGLE_THRESHOLD
           if (move > this.WIGGLE_THRESHOLD) {
             p.tracking = true;
             this.fireTrack('trackstart', p.downEvent, p);
             this.fireTrack('track', inEvent, p);
           }
         } else {
           this.fireTrack('track', inEvent, p);
         }
       }
     },
     pointerup: function(inEvent) {
       var p = pointermap.get(inEvent.pointerId);
       if (p) {
         if (p.tracking) {
           this.fireTrack('trackend', inEvent, p);
         }
         pointermap.delete(inEvent.pointerId);
       }
     },
     pointercancel: function(inEvent) {
       this.pointerup(inEvent);
     }
   };
   dispatcher.registerRecognizer('track', track);
 })(window.PointerGestures);
<|endoftext|>


<commit_before>/*
	curl-to-Go
	by Matt Holt

	https://github.com/mholt/curl-to-go

	A simple utility to convert curl commands into Go code.
*/

function curlToGo(curl) {
	var err = 'if err != nil {\n\t// handle err\n}\n';
	var deferClose = 'defer resp.Body.Close()\n';
	var promo = "// Generated by curl-to-Go: https://mholt.github.io/curl-to-go";

	// List of curl flags that are boolean typed; this helps with parsing
	// a command like `curl -abc value` to know whether 'value' belongs to '-c'
	// or is just a positional argument instead.
	var boolOptions = ['#', 'progress-bar', '-', 'next', '0', 'http1.0', 'http1.1', 'http2',
		'no-npn', 'no-alpn', '1', 'tlsv1', '2', 'sslv2', '3', 'sslv3', '4', 'ipv4', '6', 'ipv6',
		'a', 'append', 'anyauth', 'B', 'use-ascii', 'basic', 'compressed', 'create-dirs',
		'crlf', 'digest', 'disable-eprt', 'disable-epsv', 'environment', 'cert-status',
		'false-start', 'f', 'fail', 'ftp-create-dirs', 'ftp-pasv', 'ftp-skip-pasv-ip',
		'ftp-pret', 'ftp-ssl-ccc', 'ftp-ssl-control', 'g', 'globoff', 'G', 'get',
		'ignore-content-length', 'i', 'include', 'I', 'head', 'j', 'junk-session-cookies',
		'J', 'remote-header-name', 'k', 'insecure', 'l', 'list-only', 'L', 'location',
		'location-trusted', 'metalink', 'n', 'netrc', 'N', 'no-buffer', 'netrc-file',
		'netrc-optional', 'negotiate', 'no-keepalive', 'no-sessionid', 'ntlm', 'O',
		'remote-name', 'oauth2-bearer', 'p', 'proxy-tunnel', 'path-as-is', 'post301', 'post302',
		'post303', 'proxy-anyauth', 'proxy-basic', 'proxy-digest', 'proxy-negotiate',
		'proxy-ntlm', 'q', 'raw', 'remote-name-all', 's', 'silent', 'sasl-ir', 'S', 'show-error',
		'ssl', 'ssl-reqd', 'ssl-allow-beast', 'ssl-no-revoke', 'socks5-gssapi-nec', 'tcp-nodelay',
		'tlsv1.0', 'tlsv1.1', 'tlsv1.2', 'tr-encoding', 'trace-time', 'v', 'verbose', 'xattr',
		'h', 'help', 'M', 'manual', 'V', 'version'];

	if (!curl.trim())
		return;
	var cmd = parseCommand(curl, { boolFlags: boolOptions });

	if (cmd._[0] != "curl")
		throw "Not a curl command";

	var req = extractRelevantPieces(cmd);

	if (req.headers.length == 0 && !req.data.ascii && !req.data.files && !req.basicauth) {
		return promo+"\n"+renderSimple(req.method, req.url);
	} else {
		return promo+"\n\n"+renderComplex(req);
	}

	// renderSimple renders a simple HTTP request using net/http convenience methods
	function renderSimple(method, url) {
		if (method == "GET")
			return 'resp, err := http.Get("'+url+'")\n'+err+deferClose;
		else if (method == "POST")
			return 'resp, err := http.Post("'+url+'", "", nil)\n'+err+deferClose;
		else if (method == "HEAD")
			return 'resp, err := http.Head("'+url+'")\n'+err+deferClose;
		else
			return 'req, err := http.NewRequest("'+method+'", "'+url+'", nil)\n'+err+'client := http.Client{}\nresp, err := client.Do(req)\n'+err+deferClose;
	}

	// renderComplex renders Go code that uses http.Client.
	function renderComplex(req) {
		var go = "";

		// First, figure out the headers
		var headers = {};
		for (var i = 0; i < req.headers.length; i++) {
			var split = req.headers[i].indexOf(":");
			if (split == -1) continue;
			var name = req.headers[i].substr(0, split).trim();
			var value = req.headers[i].substr(split+1).trim();
			headers[toTitleCase(name)] = value;
		}

		// load body data
		// KNOWN ISSUE: -d and --data are treated like --data-binary in
		// that we don't strip out carriage returns and newlines.
		var defaultPayloadVar = "body";
		if (!req.data.ascii && !req.data.files) {
			// no data; this is easy
			go += 'req, err := http.NewRequest("'+req.method+'", "'+goEsc(req.url)+'", nil)\n'+err;
		} else {
			var ioReaders = [];

			// if there's text data...
			if (req.data.ascii) {
				var stringBody = function() {
					go += defaultPayloadVar+' := strings.NewReader(`'+req.data.ascii+'`)\n'
					ioReaders.push(defaultPayloadVar);
				}

				if (headers["Content-Type"] && headers["Content-Type"].indexOf("json") > -1) {
					// create a struct for the JSON
					var result = jsonToGo(req.data.ascii, "Payload");
					if (result.error)
						stringBody(); // not valid JSON, so just treat as a regular string
					else if (result.go) {
						// valid JSON, so create a struct to hold it
						go += result.go+'\n\ndata := Payload{\n\t// fill struct\n}\n';
						go += 'payloadBytes, err := json.Marshal(data)\n'+err;
						go += defaultPayloadVar+' := bytes.NewReader(payloadBytes)\n\n';
					}
				} else {
					// not a json Content-Type, so treat as string
					stringBody();
				}
			}

			// if file data...
			if (req.data.files && req.data.files.length > 0) {
				var varName = "f";
				for (var i = 0; i < req.data.files.length; i++) {
					var thisVarName = (req.data.files.length > 1 ? varName+(i+1) : varName);
					go += thisVarName+', err := os.Open("'+goEsc(req.data.files[i])+'")\n'+err;
					go += 'defer '+thisVarName+'.Close()\n';
					ioReaders.push(thisVarName);
				}
			}

			// render go code to put all the data in the body, concatenating if necessary
			var payloadVar = defaultPayloadVar;
			if (ioReaders.length > 0)
				payloadVar = ioReaders[0];
			if (ioReaders.length > 1) {
				payloadVar = "payload";
				// KNOWN ISSUE: The way we separate file and ascii data values
				// loses the order between them... our code above just puts the
				// ascii values first, followed by the files.
				go += 'payload := io.MultiReader('+ioReaders.join(", ")+')\n';
			}
			go += 'req, err := http.NewRequest("'+req.method+'", "'+goEsc(req.url)+'", '+payloadVar+')\n'+err;
		}

		// set basic auth
		if (req.basicauth) {
			go += 'req.SetBasicAuth("'+goEsc(req.basicauth.user)+'", "'+goEsc(req.basicauth.pass)+'")\n';
		}

		// Set headers
		for (var name in headers) {
			go += 'req.Header.Set("'+goEsc(name)+'", "'+goEsc(headers[name])+'")\n';
		}

		// create the client and execute request
		go += "\nclient := http.Client{}\nresp, err := client.Do(req)\n";
		go += err+deferClose;

		return go;
	}

	// extractRelevantPieces returns an object with relevant pieces
	// extracted from cmd, the parsed command. This accounts for
	// multiple flags that do the same thing and return structured
	// data that makes it easy to spit out Go code.
	function extractRelevantPieces(cmd) {
		var relevant = {
			url: "",
			method: "",
			headers: [],
			data: {}
		};

		// curl supports multiple URLs but we'll just use the first
		if (cmd._.length > 1)
			relevant.url = cmd._[1]; // position 1 because index 0 is the curl command itself

		// gather the headers together
		if (cmd.H)
			relevant.headers = relevant.headers.concat(cmd.H);
		if (cmd.header)
			relevant.headers = relevant.headers.concat(cmd.header);

		// set method to HEAD?
		if (cmd.I || cmd.head)
			relevant.method = "HEAD";

		// between -X and --request, prefer the long form I guess
		if (cmd.request && cmd.request.length > 0)
			relevant.method = cmd.request[cmd.request.length-1].toUpperCase();
		else if (cmd.X && cmd.X.length > 0)
			relevant.method = cmd.X[cmd.X.length-1].toUpperCase(); // if multiple, use last (according to curl docs)

		// join multiple request body data, if any
		var dataAscii = [];
		var dataFiles = [];
		var loadData = function(d) {
			if (!relevant.method)
				relevant.method = "POST";
			for (var i = 0; i < d.length; i++)
			{
				if (d[i].length > 0 && d[i][0] == "@")
					dataFiles.push(d[i].substr(1));
				else
					dataAscii.push(d[i]);
			}
		};
		if (cmd.d)
			loadData(cmd.d);
		if (cmd.data)
			loadData(cmd.data);
		if (dataAscii.length > 0)
			relevant.data.ascii = dataAscii.join("&");
		if (dataFiles.length > 0)
			relevant.data.files = dataFiles;

		// between -u and --user, choose the long form...
		var basicAuthString = "";
		if (cmd.user && cmd.user.length > 0)
			basicAuthString = cmd.user[cmd.user.length-1];
		else if (cmd.u && cmd.u.length > 0)
			basicAuthString = cmd.u[cmd.u.length-1];
		var basicAuthSplit = basicAuthString.indexOf(":");
		if (basicAuthSplit > -1) {
			relevant.basicauth = {
				user: basicAuthString.substr(0, basicAuthSplit),
				pass: basicAuthString.substr(basicAuthSplit+1)
			};
		} else {
			relevant.basicAuth = { user: basicAuthString, pass: "<PASSWORD>" };
		}

		// default to GET if nothing else specified
		if (!relevant.method)
			relevant.method = "GET";

		return relevant;
	}

	function toTitleCase(str) {
		return str.replace(/\w*/g, function(txt) {
			return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
		});
	}

	// goEsc escapes characters in s so that it is safe to use s in a "quoted string" in a Go program
	function goEsc(s) {
		return s.replace('"', '\\"').replace('\\', '\\\\');
	}
}

function parseCommand(input, options) {
	if (typeof options === 'undefined') {
		options = {};
	}

	var result = {_: []}, // what we return
	    cursor = 0,       // iterator position
	    token = "";       // current token (word or quoted string) being built

	// trim leading $ or # that may have been left in
	input = input.trim();
	if (input.length > 2 && (input[0] == '$' || input[0] == '#') && whitespace(input[1]))
		input = input.substr(1).trim();

	for (cursor = 0; cursor < input.length; cursor++) {
		if (whitespace(input[cursor]))
			continue;
		if (input[cursor] == "-") {
			flagSet();
		} else {
			unflagged();
		}
	}

	return result;

	// flagSet handles flags and it assumes the current cursor
	// points to a first dash.
	function flagSet() {
		if (cursor < input.length-1 && input[cursor+1] == "-") {
			return longFlag();
		}
		cursor++; // skip leading dash
		while (cursor < input.length && !whitespace(input[cursor]))
		{
			var flagName = input[cursor];
			if (typeof result[flagName] == 'undefined') {
				result[flagName] = [];
			}
			cursor++; // skip the flag name
			if (boolFlag(flagName))
				result[flagName] = true;
			else if (Array.isArray(result[flagName]))
				result[flagName].push(nextString());
		}
	}

	// longFlag consumes a "--long-flag" sequence and
	// stores it in result.
	function longFlag() {
		cursor += 2; // skip leading dashes
		var flagName = nextString("=");
		if (boolFlag(flagName))
			result[flagName] = true;
		else {
			if (typeof result[flagName] == 'undefined') {
				result[flagName] = [];
			}
			if (Array.isArray(result[flagName])) {
				result[flagName].push(nextString());
			}
		}
	}

	// unflagged consumes the next string as an unflagged value,
	// storing it in the result.
	function unflagged() {
		result._.push(nextString());
	}

	// boolFlag returns whether a flag is known to be boolean type
	function boolFlag(flag) {
		if (Array.isArray(options.boolFlags)) {
			for (var i = 0; i < options.boolFlags.length; i++) {
				if (options.boolFlags[i] == flag)
					return true;
			}
		}
		return false;
	}

	// nextString skips any leading whitespace and consumes the next
	// space-delimited string value and returns it. If endChar is set,
	// it will be used to determine the end of the string. Normally just
	// unescaped whitespace is the end of the string, but endChar can
	// be used to specify another end-of-string.
	function nextString(endChar) {
		for (; cursor < input.length && whitespace(input[cursor]); cursor++); // skip whitespace

		var str = "";

		var quoted = false,
			quoteCh = "",
			escaped = false;

		if (input[cursor] == '"' || input[cursor] == "'") {
			quoted = true;
			quoteCh = input[cursor];
			cursor++;
		}

		for (; cursor < input.length; cursor++) {
			if (quoted) {
				if (input[cursor] == quoteCh && !escaped) {
					cursor++; // skip closing quote
					return str;
				}
			}
			if (!quoted) {
				if (!escaped) {
					if (whitespace(input[cursor])) {
						return str;
					}
					if (endChar && input[cursor] == endChar) {
						cursor++; // skip the endChar
						return str;
					}
				}
			}
			str += input[cursor];
			escaped = false;
			if (input[cursor] == "\\") {
				escaped = true;
			}
		}

		return str;
	}

	// whitespace returns true if ch is a whitespace character.
	function whitespace(ch) {
		return ch == " " || ch == "\t" || ch == "\n" || ch == "\r";
	}
}
<commit_msg>Use http.DefaultClient (closes #2)<commit_after>/*
	curl-to-Go
	by Matt Holt

	https://github.com/mholt/curl-to-go

	A simple utility to convert curl commands into Go code.
*/

function curlToGo(curl) {
	var err = 'if err != nil {\n\t// handle err\n}\n';
	var deferClose = 'defer resp.Body.Close()\n';
	var promo = "// Generated by curl-to-Go: https://mholt.github.io/curl-to-go";

	// List of curl flags that are boolean typed; this helps with parsing
	// a command like `curl -abc value` to know whether 'value' belongs to '-c'
	// or is just a positional argument instead.
	var boolOptions = ['#', 'progress-bar', '-', 'next', '0', 'http1.0', 'http1.1', 'http2',
		'no-npn', 'no-alpn', '1', 'tlsv1', '2', 'sslv2', '3', 'sslv3', '4', 'ipv4', '6', 'ipv6',
		'a', 'append', 'anyauth', 'B', 'use-ascii', 'basic', 'compressed', 'create-dirs',
		'crlf', 'digest', 'disable-eprt', 'disable-epsv', 'environment', 'cert-status',
		'false-start', 'f', 'fail', 'ftp-create-dirs', 'ftp-pasv', 'ftp-skip-pasv-ip',
		'ftp-pret', 'ftp-ssl-ccc', 'ftp-ssl-control', 'g', 'globoff', 'G', 'get',
		'ignore-content-length', 'i', 'include', 'I', 'head', 'j', 'junk-session-cookies',
		'J', 'remote-header-name', 'k', 'insecure', 'l', 'list-only', 'L', 'location',
		'location-trusted', 'metalink', 'n', 'netrc', 'N', 'no-buffer', 'netrc-file',
		'netrc-optional', 'negotiate', 'no-keepalive', 'no-sessionid', 'ntlm', 'O',
		'remote-name', 'oauth2-bearer', 'p', 'proxy-tunnel', 'path-as-is', 'post301', 'post302',
		'post303', 'proxy-anyauth', 'proxy-basic', 'proxy-digest', 'proxy-negotiate',
		'proxy-ntlm', 'q', 'raw', 'remote-name-all', 's', 'silent', 'sasl-ir', 'S', 'show-error',
		'ssl', 'ssl-reqd', 'ssl-allow-beast', 'ssl-no-revoke', 'socks5-gssapi-nec', 'tcp-nodelay',
		'tlsv1.0', 'tlsv1.1', 'tlsv1.2', 'tr-encoding', 'trace-time', 'v', 'verbose', 'xattr',
		'h', 'help', 'M', 'manual', 'V', 'version'];

	if (!curl.trim())
		return;
	var cmd = parseCommand(curl, { boolFlags: boolOptions });

	if (cmd._[0] != "curl")
		throw "Not a curl command";

	var req = extractRelevantPieces(cmd);

	if (req.headers.length == 0 && !req.data.ascii && !req.data.files && !req.basicauth) {
		return promo+"\n"+renderSimple(req.method, req.url);
	} else {
		return promo+"\n\n"+renderComplex(req);
	}

	// renderSimple renders a simple HTTP request using net/http convenience methods
	function renderSimple(method, url) {
		if (method == "GET")
			return 'resp, err := http.Get("'+url+'")\n'+err+deferClose;
		else if (method == "POST")
			return 'resp, err := http.Post("'+url+'", "", nil)\n'+err+deferClose;
		else if (method == "HEAD")
			return 'resp, err := http.Head("'+url+'")\n'+err+deferClose;
		else
			return 'req, err := http.NewRequest("'+method+'", "'+url+'", nil)\n'+err+'resp, err := http.DefaultClient.Do(req)\n'+err+deferClose;
	}

	// renderComplex renders Go code that requires making a http.Request.
	function renderComplex(req) {
		var go = "";

		// First, figure out the headers
		var headers = {};
		for (var i = 0; i < req.headers.length; i++) {
			var split = req.headers[i].indexOf(":");
			if (split == -1) continue;
			var name = req.headers[i].substr(0, split).trim();
			var value = req.headers[i].substr(split+1).trim();
			headers[toTitleCase(name)] = value;
		}

		// load body data
		// KNOWN ISSUE: -d and --data are treated like --data-binary in
		// that we don't strip out carriage returns and newlines.
		var defaultPayloadVar = "body";
		if (!req.data.ascii && !req.data.files) {
			// no data; this is easy
			go += 'req, err := http.NewRequest("'+req.method+'", "'+goEsc(req.url)+'", nil)\n'+err;
		} else {
			var ioReaders = [];

			// if there's text data...
			if (req.data.ascii) {
				var stringBody = function() {
					go += defaultPayloadVar+' := strings.NewReader(`'+req.data.ascii+'`)\n'
					ioReaders.push(defaultPayloadVar);
				}

				if (headers["Content-Type"] && headers["Content-Type"].indexOf("json") > -1) {
					// create a struct for the JSON
					var result = jsonToGo(req.data.ascii, "Payload");
					if (result.error)
						stringBody(); // not valid JSON, so just treat as a regular string
					else if (result.go) {
						// valid JSON, so create a struct to hold it
						go += result.go+'\n\ndata := Payload{\n\t// fill struct\n}\n';
						go += 'payloadBytes, err := json.Marshal(data)\n'+err;
						go += defaultPayloadVar+' := bytes.NewReader(payloadBytes)\n\n';
					}
				} else {
					// not a json Content-Type, so treat as string
					stringBody();
				}
			}

			// if file data...
			if (req.data.files && req.data.files.length > 0) {
				var varName = "f";
				for (var i = 0; i < req.data.files.length; i++) {
					var thisVarName = (req.data.files.length > 1 ? varName+(i+1) : varName);
					go += thisVarName+', err := os.Open("'+goEsc(req.data.files[i])+'")\n'+err;
					go += 'defer '+thisVarName+'.Close()\n';
					ioReaders.push(thisVarName);
				}
			}

			// render go code to put all the data in the body, concatenating if necessary
			var payloadVar = defaultPayloadVar;
			if (ioReaders.length > 0)
				payloadVar = ioReaders[0];
			if (ioReaders.length > 1) {
				payloadVar = "payload";
				// KNOWN ISSUE: The way we separate file and ascii data values
				// loses the order between them... our code above just puts the
				// ascii values first, followed by the files.
				go += 'payload := io.MultiReader('+ioReaders.join(", ")+')\n';
			}
			go += 'req, err := http.NewRequest("'+req.method+'", "'+goEsc(req.url)+'", '+payloadVar+')\n'+err;
		}

		// set basic auth
		if (req.basicauth) {
			go += 'req.SetBasicAuth("'+goEsc(req.basicauth.user)+'", "'+goEsc(req.basicauth.pass)+'")\n';
		}

		// set headers
		for (var name in headers) {
			go += 'req.Header.Set("'+goEsc(name)+'", "'+goEsc(headers[name])+'")\n';
		}

		// execute request
		go += "\nresp, err := http.DefaultClient.Do(req)\n";
		go += err+deferClose;

		return go;
	}

	// extractRelevantPieces returns an object with relevant pieces
	// extracted from cmd, the parsed command. This accounts for
	// multiple flags that do the same thing and return structured
	// data that makes it easy to spit out Go code.
	function extractRelevantPieces(cmd) {
		var relevant = {
			url: "",
			method: "",
			headers: [],
			data: {}
		};

		// curl supports multiple URLs but we'll just use the first
		if (cmd._.length > 1)
			relevant.url = cmd._[1]; // position 1 because index 0 is the curl command itself

		// gather the headers together
		if (cmd.H)
			relevant.headers = relevant.headers.concat(cmd.H);
		if (cmd.header)
			relevant.headers = relevant.headers.concat(cmd.header);

		// set method to HEAD?
		if (cmd.I || cmd.head)
			relevant.method = "HEAD";

		// between -X and --request, prefer the long form I guess
		if (cmd.request && cmd.request.length > 0)
			relevant.method = cmd.request[cmd.request.length-1].toUpperCase();
		else if (cmd.X && cmd.X.length > 0)
			relevant.method = cmd.X[cmd.X.length-1].toUpperCase(); // if multiple, use last (according to curl docs)

		// join multiple request body data, if any
		var dataAscii = [];
		var dataFiles = [];
		var loadData = function(d) {
			if (!relevant.method)
				relevant.method = "POST";
			for (var i = 0; i < d.length; i++)
			{
				if (d[i].length > 0 && d[i][0] == "@")
					dataFiles.push(d[i].substr(1));
				else
					dataAscii.push(d[i]);
			}
		};
		if (cmd.d)
			loadData(cmd.d);
		if (cmd.data)
			loadData(cmd.data);
		if (dataAscii.length > 0)
			relevant.data.ascii = dataAscii.join("&");
		if (dataFiles.length > 0)
			relevant.data.files = dataFiles;

		// between -u and --user, choose the long form...
		var basicAuthString = "";
		if (cmd.user && cmd.user.length > 0)
			basicAuthString = cmd.user[cmd.user.length-1];
		else if (cmd.u && cmd.u.length > 0)
			basicAuthString = cmd.u[cmd.u.length-1];
		var basicAuthSplit = basicAuthString.indexOf(":");
		if (basicAuthSplit > -1) {
			relevant.basicauth = {
				user: basicAuthString.substr(0, basicAuthSplit),
				pass: basicAuthString.substr(basicAuthSplit+1)
			};
		} else {
			relevant.basicAuth = { user: basicAuthString, pass: "<PASSWORD>" };
		}

		// default to GET if nothing else specified
		if (!relevant.method)
			relevant.method = "GET";

		return relevant;
	}

	function toTitleCase(str) {
		return str.replace(/\w*/g, function(txt) {
			return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
		});
	}

	// goEsc escapes characters in s so that it is safe to use s in a "quoted string" in a Go program
	function goEsc(s) {
		return s.replace('"', '\\"').replace('\\', '\\\\');
	}
}

function parseCommand(input, options) {
	if (typeof options === 'undefined') {
		options = {};
	}

	var result = {_: []}, // what we return
	    cursor = 0,       // iterator position
	    token = "";       // current token (word or quoted string) being built

	// trim leading $ or # that may have been left in
	input = input.trim();
	if (input.length > 2 && (input[0] == '$' || input[0] == '#') && whitespace(input[1]))
		input = input.substr(1).trim();

	for (cursor = 0; cursor < input.length; cursor++) {
		if (whitespace(input[cursor]))
			continue;
		if (input[cursor] == "-") {
			flagSet();
		} else {
			unflagged();
		}
	}

	return result;

	// flagSet handles flags and it assumes the current cursor
	// points to a first dash.
	function flagSet() {
		if (cursor < input.length-1 && input[cursor+1] == "-") {
			return longFlag();
		}
		cursor++; // skip leading dash
		while (cursor < input.length && !whitespace(input[cursor]))
		{
			var flagName = input[cursor];
			if (typeof result[flagName] == 'undefined') {
				result[flagName] = [];
			}
			cursor++; // skip the flag name
			if (boolFlag(flagName))
				result[flagName] = true;
			else if (Array.isArray(result[flagName]))
				result[flagName].push(nextString());
		}
	}

	// longFlag consumes a "--long-flag" sequence and
	// stores it in result.
	function longFlag() {
		cursor += 2; // skip leading dashes
		var flagName = nextString("=");
		if (boolFlag(flagName))
			result[flagName] = true;
		else {
			if (typeof result[flagName] == 'undefined') {
				result[flagName] = [];
			}
			if (Array.isArray(result[flagName])) {
				result[flagName].push(nextString());
			}
		}
	}

	// unflagged consumes the next string as an unflagged value,
	// storing it in the result.
	function unflagged() {
		result._.push(nextString());
	}

	// boolFlag returns whether a flag is known to be boolean type
	function boolFlag(flag) {
		if (Array.isArray(options.boolFlags)) {
			for (var i = 0; i < options.boolFlags.length; i++) {
				if (options.boolFlags[i] == flag)
					return true;
			}
		}
		return false;
	}

	// nextString skips any leading whitespace and consumes the next
	// space-delimited string value and returns it. If endChar is set,
	// it will be used to determine the end of the string. Normally just
	// unescaped whitespace is the end of the string, but endChar can
	// be used to specify another end-of-string.
	function nextString(endChar) {
		for (; cursor < input.length && whitespace(input[cursor]); cursor++); // skip whitespace

		var str = "";

		var quoted = false,
			quoteCh = "",
			escaped = false;

		if (input[cursor] == '"' || input[cursor] == "'") {
			quoted = true;
			quoteCh = input[cursor];
			cursor++;
		}

		for (; cursor < input.length; cursor++) {
			if (quoted) {
				if (input[cursor] == quoteCh && !escaped) {
					cursor++; // skip closing quote
					return str;
				}
			}
			if (!quoted) {
				if (!escaped) {
					if (whitespace(input[cursor])) {
						return str;
					}
					if (endChar && input[cursor] == endChar) {
						cursor++; // skip the endChar
						return str;
					}
				}
			}
			str += input[cursor];
			escaped = false;
			if (input[cursor] == "\\") {
				escaped = true;
			}
		}

		return str;
	}

	// whitespace returns true if ch is a whitespace character.
	function whitespace(ch) {
		return ch == " " || ch == "\t" || ch == "\n" || ch == "\r";
	}
}
<|endoftext|>


<commit_before>/*
 * MIT License
 *
 * Copyright (c) 2017 Stefano Cappa
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const webpack = require('webpack');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');

const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const AutoDllPlugin = require('autodll-webpack-plugin');

const commonConfig = require('./webpack.common');
const helpers = require('./helpers');

const ENV = process.env.NODE_ENV = 'dev';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;

const METADATA = {
  env: ENV,
  host: HOST,
  portServer: '3000',
  portWebpackDevServer: PORT,
  portBrowserSync: '3300'
};

const MAIN_SERVER_PATH = `http://${METADATA.host}:${METADATA.portServer}`;
const DEV_SERVER_PATH = `http://${METADATA.host}:${METADATA.portWebpackDevServer}`;

module.exports = webpackMerge(commonConfig, {
  devtool: 'cheap-module-source-map',
  output: {
    path: helpers.root('dist'),
    filename: '[name].js',
    sourceMapFilename: '[file].map',
    chunkFilename: '[name].js',
    publicPath: '/',
    library: 'ac_[name]',
    libraryTarget: 'var'
  },
  devServer: {
    hot: true, // MANDATORY FOR HMR
    inline: true,
    port: METADATA.portWebpackDevServer,
    historyApiFallback: true,
    watchOptions: {
      aggregateTimeout: 300,
      poll: 1000,
      ignored: /node_modules/
    },
    stats: {colors: true},
    proxy: {
      //proxy all paths of the main
      //server (executed with gulp (not with nodemon))
      "/api/**": MAIN_SERVER_PATH
    }
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.ts$/,
        use: [
          {
            loader: 'tslint-loader',
            options: {
              configFile: 'tslint.json'
            }
          }
        ],
        exclude: [/\.(spec|e2e)\.ts$/, /node_modules/]
      },

      /*
       * css loader support for *.css files (styles directory only)
       * Loads external css styles into the DOM, supports HMR
       */
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
        include: [helpers.root('src', 'styles')]
      },

      /*
       * sass loader support for *.scss files (styles directory only)
       * Loads external sass styles into the DOM, supports HMR
       */
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        include: [helpers.root('src', 'styles')]
      }
    ]
  },
  plugins: [
    new HotModuleReplacementPlugin(),
    new ExtractTextPlugin({
      filename: '[name].css',
      allChunks: true
    }),
    new DefinePlugin({'webpack': {'ENV': JSON.stringify(METADATA.env)}}),

    new AutoDllPlugin({
      debug: true,
      inject: true,
      context: __dirname,
      filename: '[name]_[hash].js',
      path: helpers.root('dll'),
      entry: {
        polyfills: [
          'core-js',
          'zone.js/dist/zone.js',
          'zone.js/dist/long-stack-trace-zone'
        ],
        vendor: [
          '@angular/platform-browser',
          '@angular/platform-browser-dynamic',
          '@angular/core',
          '@angular/common',
          '@angular/forms',
          '@angular/http',
          '@angular/router',
          '@angularclass/hmr',
          'rxjs',
          '@ng-bootstrap/ng-bootstrap',
          'jquery',
          'bootstrap-loader',
          'hammerjs',
          'lodash',
          'mousetrap',
          'ng2-validators',
          'reflect-metadata',
          'tether'
        ]
      }
    }),

    new BrowserSyncPlugin(
      // BrowserSync options
      {
        // browse to http://${METADATA:host}:${METADATA.portBrowserSync}/
        // during development
        host: METADATA.host,
        port: METADATA.portBrowserSync,
        // proxy the Webpack Dev Server endpoint
        // (which should be serving on DEV_SERVER_PATH) through BrowserSync
        proxy: DEV_SERVER_PATH
      },
      // plugin options
      {
        // prevent BrowserSync from reloading the page
        // and let Webpack Dev Server take care of this
        // (useful if you want to use HMR)
        reload: false
      }
    ),
    new LoaderOptionsPlugin({
      debug: true,
      options: {}
    }),
  ],
  node: {
    global: true,
    crypto: 'empty',
    process: true,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }
});
<commit_msg>autodll improved<commit_after>/*
 * MIT License
 *
 * Copyright (c) 2017 Stefano Cappa
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const webpack = require('webpack');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');

const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const AutoDllPlugin = require('autodll-webpack-plugin');

const commonConfig = require('./webpack.common');
const helpers = require('./helpers');

const ENV = process.env.NODE_ENV = 'dev';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;

const METADATA = {
  env: ENV,
  host: HOST,
  portServer: '3000',
  portWebpackDevServer: PORT,
  portBrowserSync: '3300'
};

const MAIN_SERVER_PATH = `http://${METADATA.host}:${METADATA.portServer}`;
const DEV_SERVER_PATH = `http://${METADATA.host}:${METADATA.portWebpackDevServer}`;

module.exports = webpackMerge(commonConfig, {
  devtool: 'cheap-module-source-map',
  output: {
    path: helpers.root('dist'),
    filename: '[name].js',
    sourceMapFilename: '[file].map',
    chunkFilename: '[name].js',
    publicPath: '/',
    library: 'ac_[name]',
    libraryTarget: 'var'
  },
  devServer: {
    hot: true, // MANDATORY FOR HMR
    inline: true,
    port: METADATA.portWebpackDevServer,
    historyApiFallback: true,
    watchOptions: {
      aggregateTimeout: 300,
      poll: 1000,
      ignored: /node_modules/
    },
    stats: {colors: true},
    proxy: {
      //proxy all paths of the main
      //server (executed with gulp (not with nodemon))
      "/api/**": MAIN_SERVER_PATH
    }
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.ts$/,
        use: [
          {
            loader: 'tslint-loader',
            options: {
              configFile: 'tslint.json'
            }
          }
        ],
        exclude: [/\.(spec|e2e)\.ts$/, /node_modules/]
      },

      /*
       * css loader support for *.css files (styles directory only)
       * Loads external css styles into the DOM, supports HMR
       */
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
        include: [helpers.root('src', 'styles')]
      },

      /*
       * sass loader support for *.scss files (styles directory only)
       * Loads external sass styles into the DOM, supports HMR
       */
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        include: [helpers.root('src', 'styles')]
      }
    ]
  },
  plugins: [
    new HotModuleReplacementPlugin(),
    new ExtractTextPlugin({
      filename: '[name].css',
      allChunks: true
    }),
    new DefinePlugin({'webpack': {'ENV': JSON.stringify(METADATA.env)}}),

    new AutoDllPlugin({
      debug: true,
      inject: true,
      context: __dirname,
      filename: '[name]_[hash].js',
      path: helpers.root('dll'),
      entry: {
        polyfills: [
          'core-js',
          'zone.js/dist/zone.js',
          'zone.js/dist/long-stack-trace-zone'
        ],
        vendor: [
          '@angular/platform-browser',
          '@angular/platform-browser-dynamic',
          '@angular/core',
          '@angular/common',
          '@angular/forms',
          '@angular/http',
          '@angular/router',
          '@angularclass/hmr',
          '@ngrx/store',
          '@ngrx/store-devtools',
          'rxjs',
          '@ng-bootstrap/ng-bootstrap',
          'jquery',
          'bootstrap-loader',
          'hammerjs',
          'lodash',
          'mousetrap',
          'ng2-validators',
          'reflect-metadata',
          'tether'
        ]
      }
    }),

    new BrowserSyncPlugin(
      // BrowserSync options
      {
        // browse to http://${METADATA:host}:${METADATA.portBrowserSync}/
        // during development
        host: METADATA.host,
        port: METADATA.portBrowserSync,
        // proxy the Webpack Dev Server endpoint
        // (which should be serving on DEV_SERVER_PATH) through BrowserSync
        proxy: DEV_SERVER_PATH
      },
      // plugin options
      {
        // prevent BrowserSync from reloading the page
        // and let Webpack Dev Server take care of this
        // (useful if you want to use HMR)
        reload: false
      }
    ),
    new LoaderOptionsPlugin({
      debug: true,
      options: {}
    }),
  ],
  node: {
    global: true,
    crypto: 'empty',
    process: true,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }
});
<|endoftext|>


<commit_before>'use strict';

module.exports = function() {
  var express = require('express');
  var slashes = require('connect-slashes');
  var expressState = require('express-state');
  var path = require('path');
  var bodyParser = require('body-parser');
  var favicon = require('serve-favicon');
  var morganLogger = require('morgan');
  var methodOverride = require('method-override');
  var multer = require('multer');
  var routes = require('./routes');
  var errors = require('./middlewares/errors');
  var sslRedirection = require('./middlewares/ssl-redirection');
  var navigation = require('./middlewares/navigation');
  var notFound = require('./middlewares/not-found');
  var helmet = require('helmet');
  var appContext = require('../shared/context');
  var morpheus = require('../morpheus');
  var server = express();
  var fetchrPlugin = appContext.getPlugin('FetchrPlugin');

  morpheus.logger.info('creating express application');
  expressState.extend(server);
  server.set('state namespace', 'Morpheus');
  server.enable('strict routing');
  server.use(morganLogger('dev'));
  server.use(methodOverride());
  server.use(bodyParser.json());
  server.use(bodyParser.urlencoded({
    extended: true
  }));
  server.use(multer());
  server.use('/content/images', express.static(path.join(morpheus.config.appRoot, '/content/images/')));
  server.use(favicon(path.join(morpheus.config.appRoot, 'content/favicon.ico')));
  server.use(express.static(path.join(morpheus.config.appRoot, '/content/themes/', morpheus.config.theme)));

  // Use helmet to secure Express headers
  server.use(helmet.xframe());
  server.use(helmet.xssFilter());
  server.use(helmet.nosniff());
  server.use(helmet.ienoopen());
  server.use(helmet.hidePoweredBy({ setTo: 'Morpheus ' + morpheus.config.version }));

  fetchrPlugin.registerService(morpheus.services.content);
  server.use(fetchrPlugin.getXhrPath(), fetchrPlugin.getMiddleware());

  server.use(slashes());

  server.use(sslRedirection);

  server.use(navigation.call(null, appContext));

  routes(server);

  server.use(errors.call(null, morpheus.getLogger('express-loader')));
  // Assume 404 since no middleware responded
  server.use(notFound.call(null, morpheus.getLogger('express-loader')));
  return server;
};
<commit_msg>add comment fixes #20<commit_after>'use strict';

module.exports = function() {
  var express = require('express');
  var slashes = require('connect-slashes');
  var expressState = require('express-state');
  var path = require('path');
  var bodyParser = require('body-parser');
  var favicon = require('serve-favicon');
  var morganLogger = require('morgan');
  var methodOverride = require('method-override');
  var multer = require('multer');
  var routes = require('./routes');
  var errors = require('./middlewares/errors');
  var sslRedirection = require('./middlewares/ssl-redirection');
  var navigation = require('./middlewares/navigation');
  var notFound = require('./middlewares/not-found');
  var helmet = require('helmet');
  var appContext = require('../shared/context');
  var morpheus = require('../morpheus');
  var server = express();
  var fetchrPlugin = appContext.getPlugin('FetchrPlugin');

  morpheus.logger.info('creating express application');
  expressState.extend(server);
  server.set('state namespace', 'Morpheus');
  server.enable('strict routing');
  server.use(morganLogger('dev'));
  server.use(methodOverride());
  server.use(bodyParser.json());
  server.use(bodyParser.urlencoded({
    extended: true
  }));
  server.use(multer());
  server.use('/content/images', express.static(path.join(morpheus.config.appRoot, '/content/images/')));
  server.use(favicon(path.join(morpheus.config.appRoot, 'content/favicon.ico')));
  server.use(express.static(path.join(morpheus.config.appRoot, '/content/themes/', morpheus.config.theme)));

  // Use helmet to secure Express headers
  server.use(helmet.xframe());
  server.use(helmet.xssFilter());
  server.use(helmet.nosniff());
  server.use(helmet.ienoopen());

  // powered by Morpheus
  server.use(helmet.hidePoweredBy({ setTo: 'Morpheus ' + morpheus.config.version }));

  fetchrPlugin.registerService(morpheus.services.content);
  server.use(fetchrPlugin.getXhrPath(), fetchrPlugin.getMiddleware());

  server.use(slashes());

  server.use(sslRedirection);

  server.use(navigation.call(null, appContext));

  routes(server);

  server.use(errors.call(null, morpheus.getLogger('express-loader')));
  // Assume 404 since no middleware responded
  server.use(notFound.call(null, morpheus.getLogger('express-loader')));
  return server;
};
<|endoftext|>


<commit_before>angular.module('fulcrumSeed.global.shell', ['fulcrumSeed.global.directives.profile'])
	.controller('navController', [
		'$scope', '$state', '$rootScope',
		function ($scope, $state, $rootScope) {

			$rootScope.$on('authenticated', function () {
				$scope.visible = true;

				if (!$scope.$$phase) {
					$scope.$apply();
				}
			});

			$rootScope.$on('unauthenticated', function () {
				$scope.visible = false;

				if (!$scope.$$phase) {
					$scope.$apply();
				}
			});

			$scope.visible = false;
		}
	])
	.controller('badgeController', [
		'$scope', '$state', 'authSvc', '$rootScope', 'authRedirectSvc',
		'$modal', 'profileSvc',
		function ($scope, $state, authSvc, $rootScope, authRedirectSvc,
			$modal, profileSvc) {

			$scope.visible = false;

			$rootScope.$on('authenticated', function () {
				profileSvc.getClaims()
					.then(function (response) {
						$scope.claims = response.data;

						profileSvc.setProfile({ claims: $scope.claims });

						_.forOwn($scope.claims, function (value, key) {
							// TODO: extract some of these into a standard profile object?
							//console.log(key);
						});
					},
						function (error) {
							// TODO: ??
						});
			});

			$rootScope.$on('unauthenticated', function () {
				$scope.visible = false;
				$scope.profile = undefined;
			});

			$scope.logout = function () {
				$scope.visible = false;
				authSvc.logout();
				authRedirectSvc.clearRedirect();
				$rootScope.$broadcast("unauthenticated");

				window.location.reload();
			};

			$scope.login = function () {

				var loginModal = $modal.open({
					templateUrl: 'login.html',
					controller: 'loginController',
					size: 'sm',
				});

			};
		}
	])
	.controller('loginController', [
		'$scope', '$state', 'authSvc', '$rootScope', 'authRedirectSvc', '$modalInstance',
		function ($scope, $state, authSvc, $rootScope, authRedirectSvc, $modalInstance) {

			$scope.username = "";
			$scope.password = "";

			$scope.login = function () {

				console.log("Login attempt");
				console.log("Username:", $scope.email);
				console.log("Password:", $scope.password);

				authSvc.login($scope.email, $scope.password)
					.then(function () {
						$state.go("home", {}, { reload: true });
						$modalInstance.dismiss();
					}, function () {
						console.log("log in failed");
					});
			};
		}
	]);<commit_msg>debugging messages<commit_after>angular.module('fulcrumSeed.global.shell', ['fulcrumSeed.global.directives.profile'])
	.controller('navController', [
		'$scope', '$state', '$rootScope',
		function ($scope, $state, $rootScope) {

			$rootScope.$on('authenticated', function () {
				console.log('authenticated');
				$scope.visible = true;

				if (!$scope.$$phase) {
					console.log('authenticated $$phase');
					$scope.$apply();
				}
			});

			$rootScope.$on('unauthenticated', function () {
				$scope.visible = false;

				if (!$scope.$$phase) {
					$scope.$apply();
				}
			});

			$scope.visible = false;
		}
	])
	.controller('badgeController', [
		'$scope', '$state', 'authSvc', '$rootScope', 'authRedirectSvc',
		'$modal', 'profileSvc',
		function ($scope, $state, authSvc, $rootScope, authRedirectSvc,
			$modal, profileSvc) {

			$scope.visible = false;

			$rootScope.$on('authenticated', function () {
				profileSvc.getClaims()
					.then(function (response) {
						$scope.claims = response.data;

						profileSvc.setProfile({ claims: $scope.claims });

						_.forOwn($scope.claims, function (value, key) {
							// TODO: extract some of these into a standard profile object?
							//console.log(key);
						});
					},
						function (error) {
							// TODO: ??
						});
			});

			$rootScope.$on('unauthenticated', function () {
				$scope.visible = false;
				$scope.profile = undefined;
			});

			$scope.logout = function () {
				$scope.visible = false;
				authSvc.logout();
				authRedirectSvc.clearRedirect();
				$rootScope.$broadcast("unauthenticated");

				window.location.reload();
			};

			$scope.login = function () {

				var loginModal = $modal.open({
					templateUrl: 'login.html',
					controller: 'loginController',
					size: 'sm',
				});

			};
		}
	])
	.controller('loginController', [
		'$scope', '$state', 'authSvc', '$rootScope', 'authRedirectSvc', '$modalInstance',
		function ($scope, $state, authSvc, $rootScope, authRedirectSvc, $modalInstance) {

			$scope.username = "";
			$scope.password = "";

			$scope.login = function () {

				console.log("Login attempt");
				console.log("Username:", $scope.email);
				console.log("Password:", $scope.password);

				authSvc.login($scope.email, $scope.password)
					.then(function () {
						$state.go("home", {}, { reload: true });
						$modalInstance.dismiss();
					}, function () {
						console.log("log in failed");
					});
			};
		}
	]);<|endoftext|>


<commit_before>(function (ext) {

    var BLOCKS = {
      "空気":[0, 0],
      "石":[1, 0],
      "草":[2, 0],
      "土":[3, 0],
      "丸石": [4, 0],
      "木材": [5, 0],
      "水": [8, 0],
      "羊毛(白色)":[35, 0],
      "羊毛(橙色)":[35, 1],
      "羊毛(赤紫色)":[35, 2],
      "羊毛(水色)":[35, 3],
      "羊毛(黄色)": [35, 4],
      "羊毛(黄緑色)": [35, 5],
      "羊毛(桃色)": [35, 6],
      "羊毛(灰色)": [35, 7],
      "羊毛(薄灰色)": [35, 8],
      "羊毛(空色)":[35, 9],
      "羊毛(紫色)":[35, 10],
      "羊毛(青色)":[35, 11],
      "羊毛(茶色)":[35, 12],
      "羊毛(緑色)": [35, 13],
      "羊毛(赤色)": [35, 14],
      "羊毛(黒色)": [35, 15],
      "金ブロック": [41, 0],
      "炎": [51, 0]
    };
    var serverUrl = "http://localhost:8080";
    var blockType = 1;
    var blockData = 0;

    ext.reset = function() {
        $.get(serverUrl + "/reset", function() {
            console.log("reset succeeded");
        }).fail(function() {
            console.log("reset failed!");
        });
    };

    ext.postToChat = function(str) {
        $.get(serverUrl + "/post_to_chat/" + encodeURIComponent(str), function() {
            console.log("postToChat succeeded");
        }).fail(function() {
            console.log("postToChat failed!");
        });
    };

    ext.setPos = function(x, y, z) {
        $.get(serverUrl + "/set_pos/" + x + "/" + y + "/" + z, function() {
            console.log("setPos succeeded");
        }).fail(function() {
            console.log("setPos failed!");
        });
    };

    ext.setblockType = function(blockName) {
      [blockType, blockData] = BLOCKS[blockName];
    };

    ext.setBlockWithBlockName = function(x, y, z, blockName) {
        [_blockType, _blockData] = BLOCKS[blockName];
        $.get(serverUrl + "/set_block/" + x + "/" + y + "/" + z + "/" + _blockType + "/" + _blockData, function() {
            console.log("setBlockWithBlockName succeeded");
        }).fail(function() {
            console.log("setBlockWithBlockName failed!");
        });
    };

    ext.setBlock = function(x, y, z) {
        $.get(serverUrl + "/set_block/" + x + "/" + y + "/" + z + "/" + blockType + "/" + blockData, function() {
            console.log("setBlock succeeded");
        }).fail(function() {
            console.log("setBlock failed!");
        });
    };

    ext.setBlocks = function(x0, y0, z0, x1, y1, z1, blockName) {
      [_blockType, _blockData] = BLOCKS[blockName];
      $.get(serverUrl + "/set_blocks/" + x0 + "/" + y0 + "/" + z0 + "/" + x1 + "/" + y1 + "/" + z1 + "/" + _blockType + "/" + _blockData, function() {
          console.log("setBlocks succeeded");
      }).fail(function() {
          console.log("setBlocks failed!");
      });
    }

    ext._getStatus = function() {
        return { status:2, msg:'Ready' };
    };

    ext._shutdown = function() {};

    var descriptor = {
        blocks: [
            [" ", "リセットする", "reset"],
            [" ", "%s とチャットで送る", "postToChat", "Hello Minecraft"],
            [" ", "ブロックを %m.blockNames にする", "setblockType", "石"],
            [" ", "x:%n y:%n z:%n に移動する", "setPos", 0, 0, 0],
            [" ", "x:%n y:%n z:%n にブロックを置く", "setBlock", 0, 0, 0],
            [" ", "x:%n y:%n z:%n に %m.blockNames のブロックを置く", "setBlockWithBlockName", 0, 0, 0, "石"],
            [" ", "x:%n y:%n z:%n から x:%n y:%n z:%n まで %m.blockNames を置く", "setblocks", 0, 0, 0, 10, 10, 10, "石"]
        ],
        menus: {
            blockNames: Object.keys(BLOCKS)
        }
    };

    ScratchExtensions.register('ScratchX2MCPI', descriptor, ext);

})({});
<commit_msg>Fix typo.<commit_after>(function (ext) {

    var BLOCKS = {
      "空気":[0, 0],
      "石":[1, 0],
      "草":[2, 0],
      "土":[3, 0],
      "丸石": [4, 0],
      "木材": [5, 0],
      "水": [8, 0],
      "羊毛(白色)":[35, 0],
      "羊毛(橙色)":[35, 1],
      "羊毛(赤紫色)":[35, 2],
      "羊毛(水色)":[35, 3],
      "羊毛(黄色)": [35, 4],
      "羊毛(黄緑色)": [35, 5],
      "羊毛(桃色)": [35, 6],
      "羊毛(灰色)": [35, 7],
      "羊毛(薄灰色)": [35, 8],
      "羊毛(空色)":[35, 9],
      "羊毛(紫色)":[35, 10],
      "羊毛(青色)":[35, 11],
      "羊毛(茶色)":[35, 12],
      "羊毛(緑色)": [35, 13],
      "羊毛(赤色)": [35, 14],
      "羊毛(黒色)": [35, 15],
      "金ブロック": [41, 0],
      "炎": [51, 0]
    };
    var serverUrl = "http://localhost:8080";
    var blockType = 1;
    var blockData = 0;

    ext.reset = function() {
        $.get(serverUrl + "/reset", function() {
            console.log("reset succeeded");
        }).fail(function() {
            console.log("reset failed!");
        });
    };

    ext.postToChat = function(str) {
        $.get(serverUrl + "/post_to_chat/" + encodeURIComponent(str), function() {
            console.log("postToChat succeeded");
        }).fail(function() {
            console.log("postToChat failed!");
        });
    };

    ext.setPos = function(x, y, z) {
        $.get(serverUrl + "/set_pos/" + x + "/" + y + "/" + z, function() {
            console.log("setPos succeeded");
        }).fail(function() {
            console.log("setPos failed!");
        });
    };

    ext.setblockType = function(blockName) {
      [blockType, blockData] = BLOCKS[blockName];
    };

    ext.setBlockWithBlockName = function(x, y, z, blockName) {
        [_blockType, _blockData] = BLOCKS[blockName];
        $.get(serverUrl + "/set_block/" + x + "/" + y + "/" + z + "/" + _blockType + "/" + _blockData, function() {
            console.log("setBlockWithBlockName succeeded");
        }).fail(function() {
            console.log("setBlockWithBlockName failed!");
        });
    };

    ext.setBlock = function(x, y, z) {
        $.get(serverUrl + "/set_block/" + x + "/" + y + "/" + z + "/" + blockType + "/" + blockData, function() {
            console.log("setBlock succeeded");
        }).fail(function() {
            console.log("setBlock failed!");
        });
    };

    ext.setBlocks = function(x0, y0, z0, x1, y1, z1, blockName) {
      [_blockType, _blockData] = BLOCKS[blockName];
      $.get(serverUrl + "/set_blocks/" + x0 + "/" + y0 + "/" + z0 + "/" + x1 + "/" + y1 + "/" + z1 + "/" + _blockType + "/" + _blockData, function() {
          console.log("setBlocks succeeded");
      }).fail(function() {
          console.log("setBlocks failed!");
      });
    }

    ext._getStatus = function() {
        return { status:2, msg:'Ready' };
    };

    ext._shutdown = function() {};

    var descriptor = {
        blocks: [
            [" ", "リセットする", "reset"],
            [" ", "%s とチャットで送る", "postToChat", "Hello Minecraft"],
            [" ", "ブロックを %m.blockNames にする", "setblockType", "石"],
            [" ", "x:%n y:%n z:%n に移動する", "setPos", 0, 0, 0],
            [" ", "x:%n y:%n z:%n にブロックを置く", "setBlock", 0, 0, 0],
            [" ", "x:%n y:%n z:%n に %m.blockNames のブロックを置く", "setBlockWithBlockName", 0, 0, 0, "石"],
            [" ", "x:%n y:%n z:%n から x:%n y:%n z:%n まで %m.blockNames を置く", "setBlocks", 0, 0, 0, 10, 10, 10, "石"]
        ],
        menus: {
            blockNames: Object.keys(BLOCKS)
        }
    };

    ScratchExtensions.register('ScratchX2MCPI', descriptor, ext);

})({});
<|endoftext|>


<commit_before>'use strict';

var mcf = require('minecraft-protocol-forge');
var mc = require('minecraft-protocol');
var ping = mc.ping;
var assert = require('assert');

function createClientAuto(options, cb) {
  assert.ok(options, 'options is required');

  console.log('pinging',options.host);
  // TODO: refactor with DNS SRV lookup in NMP
  ping(options, function(err, response) {
    var client;

    if (err) return cb(err, null);
    console.log('ping response',response);
    // TODO: could also use ping pre-connect to save description, type, negotiate protocol etc.
    //  ^ see https://github.com/PrismarineJS/node-minecraft-protocol/issues/327

    if (response.modinfo && response.modinfo.type === 'FML') {
      // Use the list of Forge mods from the server ping, so client will match server
      var forgeMods = response.modinfo.modList;
      console.log('Using forgeMods:',forgeMods);
      client = mcf.createClient(options); // we know we can use Forge
      client.forgeMods = forgeMods; // for fmlHandshakeStep TODO: refactor, constructor?
    } else {
        client = mc.createClient(options); // vanilla
    }
    cb(null, client);
  });
}

module.exports = {
  createClientAsync: createClientAuto
};
<commit_msg>Missing ping packet not detected<commit_after>'use strict';

var mcf = require('minecraft-protocol-forge');
var mc = require('minecraft-protocol');
var ping = mc.ping;
var assert = require('assert');

function createClientAuto(options, cb) {
  assert.ok(options, 'options is required');

  console.log('pinging',options.host);
  // TODO: refactor with DNS SRV lookup in NMP
  // TODO: detect ping timeout, https://github.com/PrismarineJS/node-minecraft-protocol/issues/329
  ping(options, function(err, response) {
    var client;

    if (err) return cb(err, null);
    console.log('ping response',response);
    // TODO: could also use ping pre-connect to save description, type, negotiate protocol etc.
    //  ^ see https://github.com/PrismarineJS/node-minecraft-protocol/issues/327

    if (response.modinfo && response.modinfo.type === 'FML') {
      // Use the list of Forge mods from the server ping, so client will match server
      var forgeMods = response.modinfo.modList;
      console.log('Using forgeMods:',forgeMods);
      client = mcf.createClient(options); // we know we can use Forge
      client.forgeMods = forgeMods; // for fmlHandshakeStep TODO: refactor, constructor?
    } else {
        client = mc.createClient(options); // vanilla
    }
    cb(null, client);
  });
}

module.exports = {
  createClientAsync: createClientAuto
};
<|endoftext|>


<commit_before>// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.

/** @scope modules */

const AutoCommand = new Struct("event", "pattern", "command");

/**
 * @instance autocommands
 */
const AutoCommands = Module("autocommands", {
    requires: ["config"],

    init: function () {
        this._store = [];
    },

    __iterator__: function () util.Array.itervalues(this._store),

    /**
     * Adds a new autocommand. cmd will be executed when one of the
     * specified events occurs and the URL of the applicable buffer
     * matches regex.
     *
     * @param {Array} events The array of event names for which this
     *     autocommand should be executed.
     * @param {string} regex The URL pattern to match against the buffer URL.
     * @param {string} cmd The Ex command to run.
     */
    add: function (events, regex, cmd) {
        if (typeof events == "string") {
            events = events.split(",");
            liberator.log("DEPRECATED: the events list arg to autocommands.add() should be an array of event names");
        }
        events.forEach(function (event) {
            this._store.push(new AutoCommand(event, RegExp(regex), cmd));
        });
    },

    /**
     * Returns all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     * @returns {AutoCommand[]}
     */
    get: function (event, regex) {
        return this._store.filter(function (autoCmd) matchAutoCmd(autoCmd, event, regex));
    },

    /**
     * Deletes all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     */
    remove: function (event, regex) {
        this._store = this._store.filter(function (autoCmd) !matchAutoCmd(autoCmd, event, regex));
    },

    /**
     * Lists all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     */
    list: function (event, regex) {
        let cmds = {};

        // XXX
        this._store.forEach(function (autoCmd) {
            if (matchAutoCmd(autoCmd, event, regex)) {
                cmds[autoCmd.event] = cmds[autoCmd.event] || [];
                cmds[autoCmd.event].push(autoCmd);
            }
        });

        let list = template.commandOutput(

                    ----- Auto Commands -----

                {
                    template.map(cmds, function ([event, items])

                        {event}

                    +
                        template.map(items, function (item)

                             {item.pattern.source}
                            {item.command}

))
                }

);

        commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
    },

    /**
     * Triggers the execution of all autocommands registered for
     * event. A map of args is passed to each autocommand
     * when it is being executed.
     *
     * @param {string} event The event to fire.
     * @param {Object} args The args to pass to each autocommand.
     */
    trigger: function (event, args) {
        if (options.get("eventignore").has("all", event))
            return;

        let autoCmds = this._store.filter(function (autoCmd) autoCmd.event == event);

        liberator.echomsg("Executing " + event + " Auto commands for \"*\"", 8);

        let lastPattern = null;
        let url = args.url || "";

        for (let [, autoCmd] in Iterator(autoCmds)) {
            if (autoCmd.pattern.test(url)) {
                if (!lastPattern || lastPattern.source != autoCmd.pattern.source)
                    liberator.echomsg("Executing " + event + " Auto commands for \"" + autoCmd.pattern.source + "\"", 8);

                lastPattern = autoCmd.pattern;
                liberator.echomsg("autocommand " + autoCmd.command, 9);

                if (typeof autoCmd.command == "function") {
                    try {
                        autoCmd.command.call(autoCmd, args);
                    }
                    catch (e) {
                        liberator.reportError(e);
                        liberator.echoerr(e);
                    }
                }
                else
                    liberator.execute(commands.replaceTokens(autoCmd.command, args), null, true);
            }
        }
    }
}, {
    matchAutoCmd: function (autoCmd, event, regex) {
        return (!event || autoCmd.event == event) && (!regex || autoCmd.pattern.source == regex);
    },
}, {
    commands: function () {
        commands.add(["au[tocmd]"],
            "Execute commands automatically on events",
            function (args) {
                let [event, regex, cmd] = args;
                let events = [];

                try {
                    RegExp(regex);
                }
                catch (e) {
                    liberator.assert(false, "E475: Invalid argument: " + regex);
                }

                if (event) {
                    // NOTE: event can only be a comma separated list for |:au {event} {pat} {cmd}|
                    let validEvents = config.autocommands.map(function (event) event[0]);
                    validEvents.push("*");

                    events = event.split(",");
                    liberator.assert(events.every(function (event) validEvents.indexOf(event) >= 0),
                        "E216: No such group or event: " + event);
                }

                if (cmd) { // add new command, possibly removing all others with the same event/pattern
                    if (args.bang)
                        autocommands.remove(event, regex);
                    if (args["-javascript"])
                        cmd = eval("(function (args) { with(args) {" + cmd + "} })");
                    autocommands.add(events, regex, cmd);
                }
                else {
                    if (event == "*")
                        event = null;

                    if (args.bang) {
                        // TODO: "*" only appears to work in Vim when there is a {group} specified
                        if (args[0] != "*" || regex)
                            autocommands.remove(event, regex); // remove all
                    }
                    else
                        autocommands.list(event, regex);   // list all
                }
            }, {
                bang: true,
                completer: function (context) completion.autocmdEvent(context),
                literal: 2,
                options: [[["-javascript", "-js"], commands.OPTION_NOARG]]
            });

        [
            {
                name: "do[autocmd]",
                description: "Apply the autocommands matching the specified URL pattern to the current buffer"
            }, {
                name: "doautoa[ll]",
                description: "Apply the autocommands matching the specified URL pattern to all buffers"
            }
        ].forEach(function (command) {
            commands.add([command.name],
                command.description,
                // TODO: Perhaps this should take -args to pass to the command?
                function (args) {
                    // Vim compatible
                    if (args.length == 0)
                        return void liberator.echomsg("No matching autocommands");

                    let [event, url] = args;
                    let defaultURL = url || buffer.URL;
                    let validEvents = config.autocommands.map(function (e) e[0]);

                    // TODO: add command validators
                    liberator.assert(event != "*",
                        "E217: Can't execute autocommands for ALL events");
                    liberator.assert(validEvents.indexOf(event) >= 0,
                        "E216: No such group or event: " + args);
                    liberator.assert(autocommands.get(event).some(function (c) c.pattern.test(defaultURL)),
                        "No matching autocommands");

                    if (this.name == "doautoall" && liberator.has("tabs")) {
                        let current = tabs.index();

                        for (let i = 0; i < tabs.count; i++) {
                            tabs.select(i);
                            // if no url arg is specified use the current buffer's URL
                            autocommands.trigger(event, { url: url || buffer.URL });
                        }

                        tabs.select(current);
                    }
                    else
                        autocommands.trigger(event, { url: defaultURL });
                }, {
                    argCount: "*", // FIXME: kludged for proper error message should be "1".
                    completer: function (context) completion.autocmdEvent(context)
                });
        });
    },
    completion: function () {
        completion.setFunctionCompleter(autocommands.get, [function () config.autocommands]);

        completion.autocmdEvent = function autocmdEvent(context) {
            context.completions = config.autocommands;
        };

        completion.macro = function macro(context) {
            context.title = ["Macro", "Keys"];
            context.completions = [item for (item in events.getMacros())];
        };
    },
    options: function () {
        options.add(["eventignore", "ei"],
            "List of autocommand event names which should be ignored",
            "stringlist", "",
            {
                completer: function () config.autocommands.concat([["all", "All events"]]),
                validator: Option.validateCompleter
            });

        options.add(["focuscontent", "fc"],
            "Try to stay in normal mode after loading a web page",
            "boolean", false);
    },
});

// vim: set fdm=marker sw=4 ts=4 et:
<commit_msg>Fix a wrong reference.<commit_after>// Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.

/** @scope modules */

const AutoCommand = new Struct("event", "pattern", "command");

/**
 * @instance autocommands
 */
const AutoCommands = Module("autocommands", {
    requires: ["config"],

    init: function () {
        this._store = [];
    },

    __iterator__: function () util.Array.itervalues(this._store),

    /**
     * Adds a new autocommand. cmd will be executed when one of the
     * specified events occurs and the URL of the applicable buffer
     * matches regex.
     *
     * @param {Array} events The array of event names for which this
     *     autocommand should be executed.
     * @param {string} regex The URL pattern to match against the buffer URL.
     * @param {string} cmd The Ex command to run.
     */
    add: function (events, regex, cmd) {
        let self = this;

        if (typeof events == "string") {
            events = events.split(",");
            liberator.log("DEPRECATED: the events list arg to autocommands.add() should be an array of event names");
        }
        events.forEach(function (event) {
            self._store.push(new AutoCommand(event, RegExp(regex), cmd));
        });
    },

    /**
     * Returns all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     * @returns {AutoCommand[]}
     */
    get: function (event, regex) {
        return this._store.filter(function (autoCmd) matchAutoCmd(autoCmd, event, regex));
    },

    /**
     * Deletes all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     */
    remove: function (event, regex) {
        this._store = this._store.filter(function (autoCmd) !matchAutoCmd(autoCmd, event, regex));
    },

    /**
     * Lists all autocommands with a matching event and
     * regex.
     *
     * @param {string} event The event name filter.
     * @param {string} regex The URL pattern filter.
     */
    list: function (event, regex) {
        let cmds = {};

        // XXX
        this._store.forEach(function (autoCmd) {
            if (matchAutoCmd(autoCmd, event, regex)) {
                cmds[autoCmd.event] = cmds[autoCmd.event] || [];
                cmds[autoCmd.event].push(autoCmd);
            }
        });

        let list = template.commandOutput(

                    ----- Auto Commands -----

                {
                    template.map(cmds, function ([event, items])

                        {event}

                    +
                        template.map(items, function (item)

                             {item.pattern.source}
                            {item.command}

))
                }

);

        commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
    },

    /**
     * Triggers the execution of all autocommands registered for
     * event. A map of args is passed to each autocommand
     * when it is being executed.
     *
     * @param {string} event The event to fire.
     * @param {Object} args The args to pass to each autocommand.
     */
    trigger: function (event, args) {
        if (options.get("eventignore").has("all", event))
            return;

        let autoCmds = this._store.filter(function (autoCmd) autoCmd.event == event);

        liberator.echomsg("Executing " + event + " Auto commands for \"*\"", 8);

        let lastPattern = null;
        let url = args.url || "";

        for (let [, autoCmd] in Iterator(autoCmds)) {
            if (autoCmd.pattern.test(url)) {
                if (!lastPattern || lastPattern.source != autoCmd.pattern.source)
                    liberator.echomsg("Executing " + event + " Auto commands for \"" + autoCmd.pattern.source + "\"", 8);

                lastPattern = autoCmd.pattern;
                liberator.echomsg("autocommand " + autoCmd.command, 9);

                if (typeof autoCmd.command == "function") {
                    try {
                        autoCmd.command.call(autoCmd, args);
                    }
                    catch (e) {
                        liberator.reportError(e);
                        liberator.echoerr(e);
                    }
                }
                else
                    liberator.execute(commands.replaceTokens(autoCmd.command, args), null, true);
            }
        }
    }
}, {
    matchAutoCmd: function (autoCmd, event, regex) {
        return (!event || autoCmd.event == event) && (!regex || autoCmd.pattern.source == regex);
    },
}, {
    commands: function () {
        commands.add(["au[tocmd]"],
            "Execute commands automatically on events",
            function (args) {
                let [event, regex, cmd] = args;
                let events = [];

                try {
                    RegExp(regex);
                }
                catch (e) {
                    liberator.assert(false, "E475: Invalid argument: " + regex);
                }

                if (event) {
                    // NOTE: event can only be a comma separated list for |:au {event} {pat} {cmd}|
                    let validEvents = config.autocommands.map(function (event) event[0]);
                    validEvents.push("*");

                    events = event.split(",");
                    liberator.assert(events.every(function (event) validEvents.indexOf(event) >= 0),
                        "E216: No such group or event: " + event);
                }

                if (cmd) { // add new command, possibly removing all others with the same event/pattern
                    if (args.bang)
                        autocommands.remove(event, regex);
                    if (args["-javascript"])
                        cmd = eval("(function (args) { with(args) {" + cmd + "} })");
                    autocommands.add(events, regex, cmd);
                }
                else {
                    if (event == "*")
                        event = null;

                    if (args.bang) {
                        // TODO: "*" only appears to work in Vim when there is a {group} specified
                        if (args[0] != "*" || regex)
                            autocommands.remove(event, regex); // remove all
                    }
                    else
                        autocommands.list(event, regex);   // list all
                }
            }, {
                bang: true,
                completer: function (context) completion.autocmdEvent(context),
                literal: 2,
                options: [[["-javascript", "-js"], commands.OPTION_NOARG]]
            });

        [
            {
                name: "do[autocmd]",
                description: "Apply the autocommands matching the specified URL pattern to the current buffer"
            }, {
                name: "doautoa[ll]",
                description: "Apply the autocommands matching the specified URL pattern to all buffers"
            }
        ].forEach(function (command) {
            commands.add([command.name],
                command.description,
                // TODO: Perhaps this should take -args to pass to the command?
                function (args) {
                    // Vim compatible
                    if (args.length == 0)
                        return void liberator.echomsg("No matching autocommands");

                    let [event, url] = args;
                    let defaultURL = url || buffer.URL;
                    let validEvents = config.autocommands.map(function (e) e[0]);

                    // TODO: add command validators
                    liberator.assert(event != "*",
                        "E217: Can't execute autocommands for ALL events");
                    liberator.assert(validEvents.indexOf(event) >= 0,
                        "E216: No such group or event: " + args);
                    liberator.assert(autocommands.get(event).some(function (c) c.pattern.test(defaultURL)),
                        "No matching autocommands");

                    if (this.name == "doautoall" && liberator.has("tabs")) {
                        let current = tabs.index();

                        for (let i = 0; i < tabs.count; i++) {
                            tabs.select(i);
                            // if no url arg is specified use the current buffer's URL
                            autocommands.trigger(event, { url: url || buffer.URL });
                        }

                        tabs.select(current);
                    }
                    else
                        autocommands.trigger(event, { url: defaultURL });
                }, {
                    argCount: "*", // FIXME: kludged for proper error message should be "1".
                    completer: function (context) completion.autocmdEvent(context)
                });
        });
    },
    completion: function () {
        completion.setFunctionCompleter(autocommands.get, [function () config.autocommands]);

        completion.autocmdEvent = function autocmdEvent(context) {
            context.completions = config.autocommands;
        };

        completion.macro = function macro(context) {
            context.title = ["Macro", "Keys"];
            context.completions = [item for (item in events.getMacros())];
        };
    },
    options: function () {
        options.add(["eventignore", "ei"],
            "List of autocommand event names which should be ignored",
            "stringlist", "",
            {
                completer: function () config.autocommands.concat([["all", "All events"]]),
                validator: Option.validateCompleter
            });

        options.add(["focuscontent", "fc"],
            "Try to stay in normal mode after loading a web page",
            "boolean", false);
    },
});

// vim: set fdm=marker sw=4 ts=4 et:
<|endoftext|>