<commit_before>/*
 * Increase version number
 *
 * grunt bump
 * grunt bump:git
 * grunt bump:patch
 * grunt bump:minor
 * grunt bump:major
 * grunt bump:prepatch
 * grunt bump:preminor
 * grunt bump:premajor
 * grunt bump:prerelease
 *
 * @author Vojta Jina <vojta.jina@gmail.com>
 * @author Mathias Paumgarten <mail@mathias-paumgarten.com>
 * @author Adam Biggs <email@adambig.gs>
 */

'use strict';

var semver = require('semver');
var exec = require('child_process').exec;

module.exports = function(grunt) {

  var DESC = 'Increment the version, commit, tag and push.';
  grunt.registerTask('bump', DESC, function(versionType, incOrCommitOnly) {
    var opts = this.options({
      bumpVersion: true,
      commit: true,
      commitFiles: ['package.json'], // '-a' for all files
      commitMessage: 'Release v%VERSION%',
      createTag: true,
      dryRun: false,
      files: ['package.json'],
      gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
      globalReplace: false,
      prereleaseName: false,
      push: true,
      pushTo: 'upstream',
      regExp: false,
      setVersion: false,
      tagMessage: 'Version %VERSION%',
      tagName: 'v%VERSION%',
      updateConfigs: [], // array of config properties to update (with files)
      versionType: false
    });

    versionType = versionType || opts.versionType;
    var dryRun = grunt.option('dry-run') || opts.dryRun;

    var setVersion = grunt.option('setversion') || opts.setVersion;
    if (setVersion && !semver.valid(setVersion)) {
      setVersion = false;
    }

    var globalVersion; // when bumping multiple files
    var gitVersion;    // when bumping using `git describe`

    var VERSION_REGEXP = opts.regExp || new RegExp(
      '([\'|\"]?version[\'|\"]?[ ]*:[ ]*[\'|\"]?)(\\d+\\.\\d+\\.\\d+(-' +
      opts.prereleaseName +
      '\\.\\d+)?(-\\d+)?)[\\d||A-a|.|-]*([\'|\"]?)', 'i'
    );
    if (opts.globalReplace) {
      VERSION_REGEXP = new RegExp(VERSION_REGEXP.source, 'gi');
    }

    var done = this.async();
    var queue = [];
    var next = function() {
      if (!queue.length) {
        return done();
      }
      queue.shift()();
    };
    var runIf = function(condition, behavior) {
      if (condition) {
        queue.push(behavior);
      }
    };

    if (dryRun) {
      grunt.log.writeln('Running grunt-bump in dry mode!');
    }

    if (incOrCommitOnly === 'bump-only') {
      grunt.verbose.writeln('Only incrementing the version.');

      opts.commit = false;
      opts.createTag = false;
      opts.push = false;
    }

    if (incOrCommitOnly === 'commit-only') {
      grunt.verbose.writeln('Only committing/tagging/pushing.');

      opts.bumpVersion = false;
    }

    // GET VERSION FROM GIT
    runIf(opts.bumpVersion && versionType === 'git', function() {
      exec('git describe ' + opts.gitDescribeOptions, function(err, stdout) {
        if (err) {
          grunt.fatal('Can not get a version number using `git describe`');
        }
        gitVersion = stdout.trim();
        next();
      });
    });

    // BUMP ALL FILES
    runIf(opts.bumpVersion, function() {
      grunt.file.expand(opts.files).forEach(function(file, idx) {
        var version = null;
        var content = grunt.file.read(file).replace(
          VERSION_REGEXP,
          function(match, prefix, parsedVersion, namedPre, noNamePre, suffix) {
            var type = versionType === 'git' ? 'prerelease' : versionType;
            version = setVersion || semver.inc(
              parsedVersion, type || 'patch', gitVersion || opts.prereleaseName
            );
            return prefix + version + suffix;
          }
        );

        if (!version) {
          grunt.fatal('Can not find a version to bump in ' + file);
        }

        var logMsg = 'Version bumped to ' + version +  ' (in ' + file + ')';
        if (!dryRun) {
          grunt.file.write(file, content);
          grunt.log.ok(logMsg);
        } else {
          grunt.log.ok('bump-dry: ' + logMsg);
        }

        if (!globalVersion) {
          globalVersion = version;
        } else if (globalVersion !== version) {
          grunt.warn('Bumping multiple files with different versions!');
        }

        var configProperty = opts.updateConfigs[idx];
        if (!configProperty) {
          return;
        }

        var cfg = grunt.config(configProperty);
        if (!cfg) {
          return grunt.warn(
            'Can not update "' + configProperty + '" config, it does not exist!'
          );
        }

        cfg.version = version;
        grunt.config(configProperty, cfg);
        grunt.log.ok(configProperty + '\'s version updated');
      });
      next();
    });

    // when only committing, read the version from package.json / pkg config
    runIf(!opts.bumpVersion, function() {
      if (opts.updateConfigs.length) {
        globalVersion = grunt.config(opts.updateConfigs[0]).version;
      } else {
        globalVersion = grunt.file.readJSON(opts.files[0]).version;
      }

      next();
    });

    // COMMIT
    runIf(opts.commit, function() {
      var commitMessage = opts.commitMessage.replace(
        '%VERSION%', globalVersion
      );
      var cmd = 'git commit ' + opts.commitFiles.join(' ');
      cmd += ' -m "' + commitMessage + '"';

      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd, function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not create the commit:\n  ' + stderr);
          }
          grunt.log.ok('Committed as "' + commitMessage + '"');
          next();
        });
      }
    });

    // CREATE TAG
    runIf(opts.createTag, function() {
      var tagName = opts.tagName.replace('%VERSION%', globalVersion);
      var tagMessage = opts.tagMessage.replace('%VERSION%', globalVersion);

      var cmd = 'git tag -a ' + tagName + ' -m "' + tagMessage + '"';
      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd , function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not create the tag:\n  ' + stderr);
          }
          grunt.log.ok('Tagged as "' + tagName + '"');
          next();
        });
      }
    });

    // PUSH CHANGES
    runIf(opts.push, function() {
      var cmd = 'git push ' + opts.pushTo + ' && ';
      cmd += 'git push ' + opts.pushTo + ' --tags';
      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd, function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not push to ' + opts.pushTo + ':\n  ' + stderr);
          }
          grunt.log.ok('Pushed to ' + opts.pushTo);
          next();
        });
      }
    });

    next();
  });

  // ALIASES
  DESC = 'Increment the version only.';
  grunt.registerTask('bump-only', DESC, function(versionType) {
    grunt.task.run('bump:' + (versionType || '') + ':bump-only');
  });

  DESC = 'Commit, tag, push without incrementing the version.';
  grunt.registerTask('bump-commit', DESC, 'bump::commit-only');
};
<commit_msg>fix: undefined suffix returns undefined<commit_after>/*
 * Increase version number
 *
 * grunt bump
 * grunt bump:git
 * grunt bump:patch
 * grunt bump:minor
 * grunt bump:major
 * grunt bump:prepatch
 * grunt bump:preminor
 * grunt bump:premajor
 * grunt bump:prerelease
 *
 * @author Vojta Jina <vojta.jina@gmail.com>
 * @author Mathias Paumgarten <mail@mathias-paumgarten.com>
 * @author Adam Biggs <email@adambig.gs>
 */

'use strict';

var semver = require('semver');
var exec = require('child_process').exec;

module.exports = function(grunt) {

  var DESC = 'Increment the version, commit, tag and push.';
  grunt.registerTask('bump', DESC, function(versionType, incOrCommitOnly) {
    var opts = this.options({
      bumpVersion: true,
      commit: true,
      commitFiles: ['package.json'], // '-a' for all files
      commitMessage: 'Release v%VERSION%',
      createTag: true,
      dryRun: false,
      files: ['package.json'],
      gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
      globalReplace: false,
      prereleaseName: false,
      push: true,
      pushTo: 'upstream',
      regExp: false,
      setVersion: false,
      tagMessage: 'Version %VERSION%',
      tagName: 'v%VERSION%',
      updateConfigs: [], // array of config properties to update (with files)
      versionType: false
    });

    versionType = versionType || opts.versionType;
    var dryRun = grunt.option('dry-run') || opts.dryRun;

    var setVersion = grunt.option('setversion') || opts.setVersion;
    if (setVersion && !semver.valid(setVersion)) {
      setVersion = false;
    }

    var globalVersion; // when bumping multiple files
    var gitVersion;    // when bumping using `git describe`

    var VERSION_REGEXP = opts.regExp || new RegExp(
      '([\'|\"]?version[\'|\"]?[ ]*:[ ]*[\'|\"]?)(\\d+\\.\\d+\\.\\d+(-' +
      opts.prereleaseName +
      '\\.\\d+)?(-\\d+)?)[\\d||A-a|.|-]*([\'|\"]?)', 'i'
    );
    if (opts.globalReplace) {
      VERSION_REGEXP = new RegExp(VERSION_REGEXP.source, 'gi');
    }

    var done = this.async();
    var queue = [];
    var next = function() {
      if (!queue.length) {
        return done();
      }
      queue.shift()();
    };
    var runIf = function(condition, behavior) {
      if (condition) {
        queue.push(behavior);
      }
    };

    if (dryRun) {
      grunt.log.writeln('Running grunt-bump in dry mode!');
    }

    if (incOrCommitOnly === 'bump-only') {
      grunt.verbose.writeln('Only incrementing the version.');

      opts.commit = false;
      opts.createTag = false;
      opts.push = false;
    }

    if (incOrCommitOnly === 'commit-only') {
      grunt.verbose.writeln('Only committing/tagging/pushing.');

      opts.bumpVersion = false;
    }

    // GET VERSION FROM GIT
    runIf(opts.bumpVersion && versionType === 'git', function() {
      exec('git describe ' + opts.gitDescribeOptions, function(err, stdout) {
        if (err) {
          grunt.fatal('Can not get a version number using `git describe`');
        }
        gitVersion = stdout.trim();
        next();
      });
    });

    // BUMP ALL FILES
    runIf(opts.bumpVersion, function() {
      grunt.file.expand(opts.files).forEach(function(file, idx) {
        var version = null;
        var content = grunt.file.read(file).replace(
          VERSION_REGEXP,
          function(match, prefix, parsedVersion, namedPre, noNamePre, suffix) {
            var type = versionType === 'git' ? 'prerelease' : versionType;
            version = setVersion || semver.inc(
              parsedVersion, type || 'patch', gitVersion || opts.prereleaseName
            );
            return prefix + version + (suffix || '');
          }
        );

        if (!version) {
          grunt.fatal('Can not find a version to bump in ' + file);
        }

        var logMsg = 'Version bumped to ' + version +  ' (in ' + file + ')';
        if (!dryRun) {
          grunt.file.write(file, content);
          grunt.log.ok(logMsg);
        } else {
          grunt.log.ok('bump-dry: ' + logMsg);
        }

        if (!globalVersion) {
          globalVersion = version;
        } else if (globalVersion !== version) {
          grunt.warn('Bumping multiple files with different versions!');
        }

        var configProperty = opts.updateConfigs[idx];
        if (!configProperty) {
          return;
        }

        var cfg = grunt.config(configProperty);
        if (!cfg) {
          return grunt.warn(
            'Can not update "' + configProperty + '" config, it does not exist!'
          );
        }

        cfg.version = version;
        grunt.config(configProperty, cfg);
        grunt.log.ok(configProperty + '\'s version updated');
      });
      next();
    });

    // when only committing, read the version from package.json / pkg config
    runIf(!opts.bumpVersion, function() {
      if (opts.updateConfigs.length) {
        globalVersion = grunt.config(opts.updateConfigs[0]).version;
      } else {
        globalVersion = grunt.file.readJSON(opts.files[0]).version;
      }

      next();
    });

    // COMMIT
    runIf(opts.commit, function() {
      var commitMessage = opts.commitMessage.replace(
        '%VERSION%', globalVersion
      );
      var cmd = 'git commit ' + opts.commitFiles.join(' ');
      cmd += ' -m "' + commitMessage + '"';

      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd, function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not create the commit:\n  ' + stderr);
          }
          grunt.log.ok('Committed as "' + commitMessage + '"');
          next();
        });
      }
    });

    // CREATE TAG
    runIf(opts.createTag, function() {
      var tagName = opts.tagName.replace('%VERSION%', globalVersion);
      var tagMessage = opts.tagMessage.replace('%VERSION%', globalVersion);

      var cmd = 'git tag -a ' + tagName + ' -m "' + tagMessage + '"';
      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd , function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not create the tag:\n  ' + stderr);
          }
          grunt.log.ok('Tagged as "' + tagName + '"');
          next();
        });
      }
    });

    // PUSH CHANGES
    runIf(opts.push, function() {
      var cmd = 'git push ' + opts.pushTo + ' && ';
      cmd += 'git push ' + opts.pushTo + ' --tags';
      if (dryRun) {
        grunt.log.ok('bump-dry: ' + cmd);
        next();
      } else {
        exec(cmd, function(err, stdout, stderr) {
          if (err) {
            grunt.fatal('Can not push to ' + opts.pushTo + ':\n  ' + stderr);
          }
          grunt.log.ok('Pushed to ' + opts.pushTo);
          next();
        });
      }
    });

    next();
  });

  // ALIASES
  DESC = 'Increment the version only.';
  grunt.registerTask('bump-only', DESC, function(versionType) {
    grunt.task.run('bump:' + (versionType || '') + ':bump-only');
  });

  DESC = 'Commit, tag, push without incrementing the version.';
  grunt.registerTask('bump-commit', DESC, 'bump::commit-only');
};
<|endoftext|>


<commit_before>/*!
 * express
 * Copyright(c) 2009-2013 TJ Holowaychuk
 * Copyright(c) 2013 Roman Shtylman
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 */

var bodyParser = require('body-parser')
var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors');
var proto = require('./application');
var Route = require('./router/route');
var Router = require('./router');
var req = require('./request');
var res = require('./response');

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

/**
 * Create an express application.
 *
 * @return {Function}
 * @api public
 */

function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  mixin(app, EventEmitter.prototype, false);
  mixin(app, proto, false);

  // expose the prototype that will get set on requests
  app.request = Object.create(req, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  // expose the prototype that will get set on responses
  app.response = Object.create(res, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  app.init();
  return app;
}

/**
 * Expose the prototypes.
 */

exports.application = proto;
exports.request = req;
exports.response = res;

/**
 * Expose constructors.
 */

exports.Route = Route;
exports.Router = Router;

/**
 * Expose middleware
 */

exports.json = bodyParser.json
exports.query = require('./middleware/query');
exports.static = require('serve-static');
exports.urlencoded = bodyParser.urlencoded

/**
 * Replace removed middleware with an appropriate error message.
 */

;[
  'bodyParser',
  'compress',
  'cookieSession',
  'session',
  'logger',
  'cookieParser',
  'favicon',
  'responseTime',
  'errorHandler',
  'timeout',
  'methodOverride',
  'vhost',
  'csrf',
  'directory',
  'limit',
  'multipart',
  'staticCache',
].forEach(function (name) {
  Object.defineProperty(exports, name, {
    get: function () {
      throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
    },
    configurable: true
  });
});
<commit_msg>lint: move removed middlewares list to a variable<commit_after>/*!
 * express
 * Copyright(c) 2009-2013 TJ Holowaychuk
 * Copyright(c) 2013 Roman Shtylman
 * Copyright(c) 2014-2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 */

var bodyParser = require('body-parser')
var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors');
var proto = require('./application');
var Route = require('./router/route');
var Router = require('./router');
var req = require('./request');
var res = require('./response');

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

/**
 * Create an express application.
 *
 * @return {Function}
 * @api public
 */

function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  mixin(app, EventEmitter.prototype, false);
  mixin(app, proto, false);

  // expose the prototype that will get set on requests
  app.request = Object.create(req, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  // expose the prototype that will get set on responses
  app.response = Object.create(res, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  app.init();
  return app;
}

/**
 * Expose the prototypes.
 */

exports.application = proto;
exports.request = req;
exports.response = res;

/**
 * Expose constructors.
 */

exports.Route = Route;
exports.Router = Router;

/**
 * Expose middleware
 */

exports.json = bodyParser.json
exports.query = require('./middleware/query');
exports.static = require('serve-static');
exports.urlencoded = bodyParser.urlencoded

/**
 * Replace removed middleware with an appropriate error message.
 */

var removedMiddlewares = [
  'bodyParser',
  'compress',
  'cookieSession',
  'session',
  'logger',
  'cookieParser',
  'favicon',
  'responseTime',
  'errorHandler',
  'timeout',
  'methodOverride',
  'vhost',
  'csrf',
  'directory',
  'limit',
  'multipart',
  'staticCache'
]

removedMiddlewares.forEach(function (name) {
  Object.defineProperty(exports, name, {
    get: function () {
      throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');
    },
    configurable: true
  });
});
<|endoftext|>


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

var root = './src/main/static/';
var dist = './src/main/resources/public/';

module.exports = function (config) {
    return function (forTask) {
        return function(done) {
            if (forTask == "internal") {
                return gulp.src(
                    [
                        root+'*.html',
                        root+'docs/index.html',
                        root+'favicon.ico',
                        root+'assets/img/**',
                        root+'assets/fonts/**'
                    ],
                    {base: root}
                ).pipe(gulp.dest(dist));
            }
            else if (forTask == "awesome") {
                return gulp.src(['./node_modules/font-awesome/fonts/**.*'], {base: './node_modules/font-awesome/'})
                    .pipe(gulp.dest(dist+'assets/'));
            }
        }
    };
};<commit_msg>test javadoc marble<commit_after>/*
 * Copyright (c) 2011-2016 Pivotal Software Inc, All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var gulp = require('gulp');

var root = './src/main/static/';
var dist = './src/main/resources/public/';

module.exports = function (config) {
    return function (forTask) {
        return function(done) {
            if (forTask == "internal") {
                return gulp.src(
                    [
                        root+'*.html',
                        root+'docs/index.html',
                        root+'favicon.ico',
                        root+'assets/img/**/*.*',
                        root+'assets/fonts/**/*.*'
                    ],
                    {base: root}
                ).pipe(gulp.dest(dist));
            }
            else if (forTask == "awesome") {
                return gulp.src(['./node_modules/font-awesome/fonts/**.*'], {base: './node_modules/font-awesome/'})
                    .pipe(gulp.dest(dist+'assets/'));
            }
        }
    };
};<|endoftext|>


<commit_before>/*
 * MIT License
 *
 * Copyright (c) 2017-2020 Jan Dockx
 *
 * 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 Contract = require('@toryt/contracts-iv')
const validator = require('validator')
const validate = require('./validate')

function regexEscape (str) {
  return str.replace(/[.^$!?=+\\]/g, '\\$&')
}

const instanceOrType = [
  function (fqdn) {
    return validate.isServiceInstance(fqdn) || validate.isServiceType(fqdn)
  }
]

const extractDomain = new Contract({
  pre: instanceOrType,
  post: [
    function (fqdn, result) {
      return !!result
    },
    function (fqdn, result) {
      return typeof result === 'string'
    },
    function (fqdn, result) {
      return fqdn.endsWith(result)
    },
    function (fqdn, result) {
      return result === fqdn.match(/^.+\._(tcp|udp)\.(.*)$/)[2]
    },
    function (fqdn, result) {
      // noinspection JSUnresolvedFunction
      return validator.isFQDN(result)
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts.slice(Math.max(lastTcp, lastUdp) + 1).join('.')
})

const extractProtocol = new Contract({
  pre: instanceOrType,
  post: [
    function (fqdn, result) {
      return result === 'udp' || result === 'tcp'
    },
    function (fqdn, result) {
      return result === fqdn.match(/^.+\._(tcp|udp)\.(.*)$/)[1]
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp)].substring(1)
})

const extractType = new Contract({
  pre: instanceOrType,
  post: [
    function (fqdn, result) {
      return (
        result ===
        fqdn.match(new RegExp(`^(?:.*\\.)*_(.*?)\\._${this.protocol(fqdn)}\\.${regexEscape(this.domain(fqdn))}$`))[1]
      )
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp) - 1].substring(1)
})

const extractInstance = new Contract({
  pre: [validate.isServiceInstance],
  post: [
    function (fqdn, result) {
      return (
        result ===
        fqdn.match(
          new RegExp(
            `^(.*)\\._${regexEscape(this.type(fqdn))}\\._${this.protocol(fqdn)}\\.${regexEscape(this.domain(fqdn))}$`
          )
        )[1]
      )
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp) - 2]
})

/**
 * This is essentially the same as extracting an instance name, except that
 * - there might not be a subtype; we return `undefined`
 * - we skip the '._sub' domain name part
 * According to DNS-SD, a subtype does not have to start with a '_'. Therefor,
 * if there is a starting '_', it is part of the name, and not removed.
 */
const extractSubtype = new Contract({
  pre: [validate.isServiceType],
  post: [
    function (fqdn, result) {
      const matched = fqdn.match(
        new RegExp(
          `^(.*)\\._sub\\._${regexEscape(this.type(fqdn))}\\._${this.protocol(fqdn)}\\.${regexEscape(
            this.domain(fqdn)
          )}$`
        )
      )
      return result === (matched ? matched[1] : undefined)
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  // -1 is the service, -2 would be '_sub', everything earlier is what we want
  return parts.slice(0, Math.max(lastTcp, lastUdp, 2) - 2).join('.') || undefined
})

module.exports.domain = extractDomain
module.exports.protocol = extractProtocol
module.exports.type = extractType
module.exports.instance = extractInstance
module.exports.subtype = extractSubtype
<commit_msg>use more arrow functions in contract for readability<commit_after>/*
 * MIT License
 *
 * Copyright (c) 2017-2020 Jan Dockx
 *
 * 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 Contract = require('@toryt/contracts-iv')
const validator = require('validator')
const validate = require('./validate')

function regexEscape (str) {
  return str.replace(/[.^$!?=+\\]/g, '\\$&')
}

const instanceOrType = [
  function (fqdn) {
    return validate.isServiceInstance(fqdn) || validate.isServiceType(fqdn)
  }
]

// noinspection JSUnresolvedFunction
const extractDomain = new Contract({
  pre: instanceOrType,
  post: [
    (fqdn, result) => !!result,
    (fqdn, result) => typeof result === 'string',
    (fqdn, result) => fqdn.endsWith(result),
    (fqdn, result) => result === fqdn.match(/^.+\._(tcp|udp)\.(.*)$/)[2],
    (fqdn, result) => validator.isFQDN(result)
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts.slice(Math.max(lastTcp, lastUdp) + 1).join('.')
})

const extractProtocol = new Contract({
  pre: instanceOrType,
  post: [
    (fqdn, result) => result === 'udp' || result === 'tcp',
    (fqdn, result) => result === fqdn.match(/^.+\._(tcp|udp)\.(.*)$/)[1]
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp)].substring(1)
})

const extractType = new Contract({
  pre: instanceOrType,
  post: [
    (fqdn, result) =>
      result ===
      fqdn.match(new RegExp(`^(?:.*\\.)*_(.*?)\\._${this.protocol(fqdn)}\\.${regexEscape(this.domain(fqdn))}$`))[1]
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp) - 1].substring(1)
})

const extractInstance = new Contract({
  pre: [validate.isServiceInstance],
  post: [
    (fqdn, result) =>
      result ===
      fqdn.match(
        new RegExp(
          `^(.*)\\._${regexEscape(this.type(fqdn))}\\._${this.protocol(fqdn)}\\.${regexEscape(this.domain(fqdn))}$`
        )
      )[1]
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  return parts[Math.max(lastTcp, lastUdp) - 2]
})

/**
 * This is essentially the same as extracting an instance name, except that
 * - there might not be a subtype; we return `undefined`
 * - we skip the '._sub' domain name part
 * According to DNS-SD, a subtype does not have to start with a '_'. Therefor,
 * if there is a starting '_', it is part of the name, and not removed.
 */
const extractSubtype = new Contract({
  pre: [validate.isServiceType],
  post: [
    (fqdn, result) => {
      const matched = fqdn.match(
        new RegExp(
          `^(.*)\\._sub\\._${regexEscape(this.type(fqdn))}\\._${this.protocol(fqdn)}\\.${regexEscape(
            this.domain(fqdn)
          )}$`
        )
      )
      return result === (matched ? matched[1] : undefined)
    }
  ]
}).implementation(function extractDomain (fqdn) {
  const parts = fqdn.split('.')
  const lastTcp = parts.lastIndexOf('_tcp')
  const lastUdp = parts.lastIndexOf('_udp')
  // -1 is the service, -2 would be '_sub', everything earlier is what we want
  return parts.slice(0, Math.max(lastTcp, lastUdp, 2) - 2).join('.') || undefined
})

module.exports.domain = extractDomain
module.exports.protocol = extractProtocol
module.exports.type = extractType
module.exports.instance = extractInstance
module.exports.subtype = extractSubtype
<|endoftext|>


<commit_before>/*
 * grunt-docs
 * https://github.com/shama/grunt-docs
 *
 * Copyright (c) 2012 Kyle Robinson Young
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  grunt.registerMultiTask('docs', 'Build docs with YamYam', function() {
    var yamyam = require('YamYam'),
      path = require('path'),
      dest = this.file.dest,
      blocks = [],
      files = grunt.file.expandFiles(this.file.src);
    files.forEach(function(filepath) {
      // Ignore _ prepended files
      if (path.basename(filepath).substr(0, 1) === '_') {
        return;
      }
      // Markdown -> HTML
      yamyam.parse(grunt.file.read(filepath), function(err, html) {
        blocks.push({data: html, file: filepath});
      });
    });
    if (blocks.length > 0) {
      if (this.data.layout !== undefined) {
        var layout = require('jade').compile(grunt.file.read(this.data.layout), {
          filename: dest,
          client: false,
          compileDebug: false
        });
        if (dest.substr(-1, 1) === '*') {
          // Output multiple layout files
          blocks.forEach(function(block) {
            var name = path.basename(block.file, '.md'),
              dir = path.dirname(dest),
              html = layout({blocks:[block]}),
              filepath = path.normalize(dir + '/' + name + '.html');
            grunt.file.write(filepath, html);
            grunt.log.writeln('File ' + filepath + ' created.');
          });
        } else {
          // Output single layout file
          grunt.file.write(dest, layout({blocks:blocks}));
          grunt.log.writeln('File ' + dest + ' created.');
        }
      } else {
        // Output simple joined files
        grunt.file.write(dest, blocks.join("\n"));
        grunt.log.writeln('File ' + dest + ' created.');
      }
    }
  });
};
<commit_msg>core: fix simple joined files<commit_after>/*
 * grunt-docs
 * https://github.com/shama/grunt-docs
 *
 * Copyright (c) 2012 Kyle Robinson Young
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  grunt.registerMultiTask('docs', 'Build docs with YamYam', function() {
    var yamyam = require('YamYam'),
      path = require('path'),
      dest = this.file.dest,
      blocks = [],
      files = grunt.file.expandFiles(this.file.src);
    files.forEach(function(filepath) {
      // Ignore _ prepended files
      if (path.basename(filepath).substr(0, 1) === '_') {
        return;
      }
      // Markdown -> HTML
      yamyam.parse(grunt.file.read(filepath), function(err, html) {
        blocks.push({data: html, file: filepath});
      });
    });
    if (blocks.length > 0) {
      if (this.data.layout !== undefined) {
        var layout = require('jade').compile(grunt.file.read(this.data.layout), {
          filename: dest,
          client: false,
          compileDebug: false
        });
        if (dest.substr(-1, 1) === '*') {
          // Output multiple layout files
          blocks.forEach(function(block) {
            var name = path.basename(block.file, '.md'),
              dir = path.dirname(dest),
              html = layout({blocks:[block]}),
              filepath = path.normalize(dir + '/' + name + '.html');
            grunt.file.write(filepath, html);
            grunt.log.writeln('File ' + filepath + ' created.');
          });
        } else {
          // Output single layout file
          grunt.file.write(dest, layout({blocks:blocks}));
          grunt.log.writeln('File ' + dest + ' created.');
        }
      } else {
        // Output simple joined files to single
        grunt.file.write(dest, grunt.utils._.pluck(blocks, 'data').join("\n"));
        grunt.log.writeln('File ' + dest + ' created.');
      }
    }
  });
};
<|endoftext|>


<commit_before>"use strict";
/*
 Created by lx on 2016/11/17
 Name: Xinyu Ge
 */
const dbConnection = require("../config/mongoConnection");
const uuid = require("node-uuid");

dbConnection().then(db => {
    return db.collection("city").drop().then(function() {
        return db;
    }, function() {
        return db;
    }).then((db) => {
        return db.createCollection("city");
    }).then(function(cityCollection) {

        var createCity = (name, province, description, traffic, weather, history, culture, currency, mainImage, tag) => {
            return {
                _id: uuid.v4(),
                name: name,
                province: province,
                description: description,
                traffic: traffic,
                weather: weather,
                history: history,
                culture: culture,
                currency: currency,
                mainImage: mainImage,
                tag: tag
            }
        }

        var listOfCities = [];

        // city_1 Beijing
        var BeijingTag = ["capital", "tian'anmen"];
        var BeijingCity = createCity("Beijing", "Beijing", "Beijing Description", "Beijing Traffic", "Beijing Weather", "Beijing History", "Beijing Culture", "RMB", "Beijing Image", BeijingTag);

        // city_2 Shanghai
        var ShanghaiTag = ["Shanghai Shibohui", "Dofangmingzhu"];
        var ShanghaiCity = createCity("Shanghai", "Shanghai", "Shanghai Description", "Shanghai Traffic", "Shanghai Weather", "Shanghai History", "Shanghai Culture", "RMB", "Shanghai Image", ShanghaiTag);

        // city_3 Shenzhen
        var ShenzhenTag = ["guandong", "tequ"];
        var ShenzhenCity = createCity("Shenzhen", "Shenzhen", "Shenzhen Description", "Shenzhen Traffic", "Shenzhen Weather", "Shenzhen History", "Shenzhen Culture", "RMB", "Shenzhen Image", ShenzhenTag);

        //
        listOfCities.push(BeijingCity, ShanghaiCity, ShenzhenCity);

        return cityCollection.insertMany(listOfCities).then(() => {
            return cityCollection.find().toArray();
        });
    }).then((addedCity) => {
    	return sites.addSite("QianFoMountain", "N36°E117°", "JingShi road, JiNan, ShanDong", "Bus", "30￥", "6:00PM", "2016681367", "www.qianfoshan.com", "qianfoshan", "1.png", 1, ["climb","cable"],["mountain", "famous", "JiNan"], "fk_city");
    }).then((addedSite) => {
     	return sites.addSite("DaMingLake", "N50°E120°", "MingHu road, JiNan, ShanDong", "Bus", "60￥", "6:00PM", "2016681367", "www.daminghu.com", "daminghu", "2.png", 1, ["boat","landscape"],["lake", "famous", "JiNan", "XiaYuHe"], "fk_city");
    }).then((addedSite) => {
        return sites.addSite("BaoTuFountain", "N45°E116°", "XiMen road, JiNan, ShanDong", "Bus", "50￥", "6:00PM", "2016681367", "www.baotuquan.com", "baotuquan", "3.png", 1, ["seal","tea"],["fountain", "famous", "JiNan"], "fk_city");
    }).then((addedSite) => {
        return food.addFood("BaZiRou", "bengrouganfan", "N36°E117°", "YaoShan", "20￥", "9:30PM", "18615213327", "www.bazirou.com", "4.png", 2, "fk_city");
    }).then((addedFood) => {
        return food.addFood("TianMo", "salty vegetable porridge", "N36°E117°", "XiaoTan", "1.5￥", "10:00AM", "18615213327", "www.tianmo.com", "5.png", 2, "fk_city");
    }).then((addedFood) => {
        return food.addFood("YouXuan", "fried dough", "N36°E117°", "FuRongJie", "0.5￥", "10:30PM", "18615213327", "www.youxuan.com", "6.png", 2, "fk_city");
    }).then((added) => {
        console.log("Done seeding database!");
        db.close();
   });
}), (error) => {
     console.error(error);
};

<commit_msg>Update seed.js<commit_after>"use strict";
/*
 Created by lx on 2016/11/17
 Name: Xinyu Ge
 */
const dbConnection = require("../config/mongoConnection");
const uuid = require("node-uuid");
const data = require("../data/");
const sites = data.site;
const food = data.food;

dbConnection().then(db => {
    return db.collection("city").drop().then(function() {
        return db;
    }, function() {
        return db;
    }).then((db) => {
        return db.createCollection("city");
    }).then(function(cityCollection) {

        var createCity = (name, province, description, traffic, weather, history, culture, currency, mainImage, tag) => {
            return {
                _id: uuid.v4(),
                name: name,
                province: province,
                description: description,
                traffic: traffic,
                weather: weather,
                history: history,
                culture: culture,
                currency: currency,
                mainImage: mainImage,
                tag: tag
            }
        }

        var listOfCities = [];

        // city_1 Beijing
        var BeijingTag = ["capital", "tian'anmen"];
        var BeijingCity = createCity("Beijing", "Beijing", "Beijing Description", "Beijing Traffic", "Beijing Weather", "Beijing History", "Beijing Culture", "RMB", "Beijing Image", BeijingTag);

        // city_2 Shanghai
        var ShanghaiTag = ["Shanghai Shibohui", "Dofangmingzhu"];
        var ShanghaiCity = createCity("Shanghai", "Shanghai", "Shanghai Description", "Shanghai Traffic", "Shanghai Weather", "Shanghai History", "Shanghai Culture", "RMB", "Shanghai Image", ShanghaiTag);

        // city_3 Shenzhen
        var ShenzhenTag = ["guandong", "tequ"];
        var ShenzhenCity = createCity("Shenzhen", "Shenzhen", "Shenzhen Description", "Shenzhen Traffic", "Shenzhen Weather", "Shenzhen History", "Shenzhen Culture", "RMB", "Shenzhen Image", ShenzhenTag);

        //
        listOfCities.push(BeijingCity, ShanghaiCity, ShenzhenCity);

        return cityCollection.insertMany(listOfCities).then(() => {
            return cityCollection.find().toArray();
        });
    }).then((addedCity) => {
    	return sites.addSite("QianFoMountain", "N36°E117°", "JingShi road, JiNan, ShanDong", "Bus", "30￥", "6:00PM", "2016681367", "www.qianfoshan.com", "qianfoshan", "1.png", 1, ["climb","cable"],["mountain", "famous", "JiNan"], "fk_city");
    }).then((addedSite) => {
     	return sites.addSite("DaMingLake", "N50°E120°", "MingHu road, JiNan, ShanDong", "Bus", "60￥", "6:00PM", "2016681367", "www.daminghu.com", "daminghu", "2.png", 1, ["boat","landscape"],["lake", "famous", "JiNan", "XiaYuHe"], "fk_city");
    }).then((addedSite) => {
        return sites.addSite("BaoTuFountain", "N45°E116°", "XiMen road, JiNan, ShanDong", "Bus", "50￥", "6:00PM", "2016681367", "www.baotuquan.com", "baotuquan", "3.png", 1, ["seal","tea"],["fountain", "famous", "JiNan"], "fk_city");
    }).then((addedSite) => {
        return food.addFood("BaZiRou", "bengrouganfan", "N36°E117°", "YaoShan", "20￥", "9:30PM", "18615213327", "www.bazirou.com", "4.png", 2, "fk_city");
    }).then((addedFood) => {
        return food.addFood("TianMo", "salty vegetable porridge", "N36°E117°", "XiaoTan", "1.5￥", "10:00AM", "18615213327", "www.tianmo.com", "5.png", 2, "fk_city");
    }).then((addedFood) => {
        return food.addFood("YouXuan", "fried dough", "N36°E117°", "FuRongJie", "0.5￥", "10:30PM", "18615213327", "www.youxuan.com", "6.png", 2, "fk_city");
    }).then((added) => {
        console.log("Done seeding database!");
        db.close();
   });
}), (error) => {
     console.error(error);
};

<|endoftext|>


<commit_before>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for Docker is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var stats = require('docker-stats')
var flatten = require('flat')
var through = require('through2')
var Aggregator = require('./aggregator.js')
var SpmAgent = require('spm-agent')
var config = SpmAgent.Config
var statsCallBackFuntion = null

var opts = {
  docker: null, //  here goes options for Dockerode
  events: null,  //  an instance of docker-allcontainers,
  statsinterval: 10,
  matchByName: process.env.SPM_MATCH_BY_NAME,
  matchByImage: process.env.SPM_MATCH_BY_IMAGE,
  skipByName: process.env.SPM_SKIP_BY_NAME,
  skipByImage: process.env.SPM_SKIP_BY_IMAGE
}
// holds aggregation object for each container
var cMetrics = {}
var counter = require('measured').createCollection()

function transformStatsApi1_21 (stats) {
  if (!stats.networks) {
    return stats
  }
  var result = {
      rx_bytes: 0,
      rx_packets: 0,
      rx_errors: 0,
      rx_dropped: 0,
      tx_bytes: 0,
      tx_packets: 0,
      tx_errors: 0,
      tx_dropped: 0
  }
  Object.keys(stats.networks).forEach(function aggNetworkMetrics (key) {
    Object.keys(result).forEach(function (metric) {
      result[metric] += stats.networks[key][metric]
    })
  })
  stats.network = result
  if (process.env.spmagent_logger__level === 'debug') {
    console.log('docker stats transformStatsApi1_21: ' + JSON.stringify(stats))
  }
  return stats
}

// handling different structures of docker stats
function transformStats (stats) {
  if (process.env.spmagent_logger__level === 'debug') {
    console.log('docker stats: ' + JSON.stringify(stats))
  }
  if (stats.network && stats.network.rx_bytes) {
    // API < 1.21
    return stats
  } else {
    return transformStatsApi1_21(stats)
  }
}

function processStats (chunk, enc, cb) {
  var stats = flatten(transformStats(chunk.stats))
  var metric = {}
  if (process.env.spmagent_logger__level === 'silly') {
    console.log(stats)
  }
  counter.meter('requestsPerSecond').mark()
  if (cMetrics[chunk.id] === undefined) {
    cMetrics[chunk.id] = new Aggregator()
  }
  metric.name = chunk.name
  metric.dockerId = chunk.id
  metric.image = chunk.image
  var agg = cMetrics[chunk.id]
  agg.info = metric
  metrics.forEach(function (key) {
    var value = stats[key] || 0
    if (/service_time_/i.test(key) || /wait_time_/i.test(key)) {
      // micro seconds to ms
      value = value / (1000 * 1000)
    }
    agg.update(stats['read'], key, value, useDivForAggregation[key] || false)
  })
  // setTimeout (cb, 10)
  cb()
}

function getDockerStats (dockerStatsCallback) {
  var dockerStatsStream = stats(opts)
  dockerStatsStream.pipe(through.obj(processStats))
  dockerStatsStream.on('closed', function () {
    console.log('docker stats stream closed')
    // process.exit()
  })
  dockerStatsStream.once('error', function (err) {
    console.log('docker stats stream error:' + err)
    // try to reconnect
    setTimeout(function () {
      getDockerStats(dockerStatsCallback)
    }, 15000)
    try {
      dockerStatsStream.close()
    } catch (ex) {
      console.log(ex)
    }
  })
}

function getStatsForContainer (container, aggStats) {
  var agg = cMetrics[container]
  if (!agg) {
    return null
  }
  var values = []
  aggStats.forEach(function (key) {
    var metricStats = agg.get(key)
    metricStats.id = container
    values.push(metricStats)
  })
  agg.reset()
  return values
}

var cpuMetrics = [
  // CPU
  // 'cpu_stats.cpu_usage.total_usage',
  // 'cpu_stats.cpu_usage.percpu_usage.0',
  // 'cpu_stats.cpu_usage.usage_in_kernelmode',
  // 'cpu_stats.cpu_usage.usage_in_usermode',
  'cpu_stats.cpu_usage.cpu_percent',
  // 'cpu_stats.system_cpu_usage',
  // 'cpu_stats.throttling_data.periods',
  // 'cpu_stats.throttling_data.throttled_periods',
  'cpu_stats.throttling_data.throttled_time'
]

var networkMetrics = [
  // NETWORK
  'network.rx_bytes',
  'network.rx_packets',
  'network.rx_errors',
  'network.rx_dropped',
  'network.tx_bytes',
  'network.tx_packets',
  'network.tx_errors',
  'network.tx_dropped'
]

var memoryMetrics = [
  // MEMORY
  'memory_stats.usage',
  'memory_stats.limit',
  'memory_stats.failcnt',
  // 'memory_stats.max_usage',
  // 'memory_stats.active_anon',
  // 'memory_stats.active_file',
  // 'memory_stats.cache',
  // 'memory_stats.hierarchical_memory_limit',
  // 'memory_stats.inactive_anon',
  // 'memory_stats.inactive_file',
  // 'memory_stats.mapped_file',
  'memory_stats.stats.pgfault',
  // 'memory_stats.pgmajfault',
  'memory_stats.stats.pgpgin',
  'memory_stats.stats.pgpgout'
  // 'memory_stats.ss',
  // 'memory_stats.rss_huge',
  // MEMORY FAIL COUNTER

  // MEMORY LIMIT

// MEMORY TOTAL
// 'memory_stats.total_active_anon',
// 'memory_stats.total_active_file',
// 'memory_stats.total_cache',
// 'memory_stats.total_inactive_anon',
// 'memory_total_inactive_file',
// 'memory_stats.total_mapped_file',
// 'memory_stats.total_pgfault',
// 'memory_stats.total_pgmajfault',
// 'memory_stats.total_pgpgin',
// 'memory_stats.total_pgpgout',
// 'memory_stats.total_rss',
// 'memory_stats.total_rss_huge',
// 'memory_stats.total_unevictable',
// 'memory_stats.stats.total_writeback',
// 'memory_stats.unevictable',
// 'memory_stats.writeback'
]

var ioMetrics = [
  // IO STATS
  // READ
  'blkio_stats.io_service_bytes_recursive.0.value',
  // READ time
  'blkio_stats.io_service_time_recursive.0.value',
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value',
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value',
  // Write time
  'blkio_stats.io_service_time_recursive.1.value',
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value'
// 'blkio_io_service_bytes_recursive',
// 'blkio_io_serviced_recursive',
// 'blkio_io_queue_recursive',
// 'blkio_io_service_time_recursive',
// 'blkio_io_wait_time_recursive',
// 'blkio_io_merged_recursive',
// 'blkio_io_time_recursive',
// 'blkio_sectors_recursive'
]
var metrics = []
metrics = metrics.concat(cpuMetrics).concat(networkMetrics).concat(memoryMetrics).concat(ioMetrics)
var avgAggregation = {
  'cpu_stats.cpu_usage.cpu_percent': true,
  'cpu_stats.throttling_data.throttled_time': true,
  'memory_stats.usage': true,
  'memory_stats.limit': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}
var useDivForAggregation = {
  'network.rx_bytes': true,
  'network.rx_packets': true,
  'network.rx_errors': true,
  'network.rx_dropped': true,
  'network.tx_bytes': true,
  'network.tx_packets': true,
  'network.tx_errors': true,
  'network.tx_dropped': true,
  'memory_stats.failcnt': true,
  'memory_stats.stats.pgfault': true,
  'memory_stats.stats.pgpgin': true,
  'memory_stats.stats.pgpgout': true,
  'blkio_stats.io_service_bytes_recursive.0.value': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}

function getValueAsNum (value) {
  var rv = 0
  if (!isNaN(value)) {
    rv = value
  }
  return rv
}

function getStatsValue (metric) {
  if (avgAggregation[metric.name]) {
    return getValueAsNum(metric.mean)
  } else {
    return getValueAsNum(metric.sum)
  }
}
function dockerStatsCollector (statsCallback) {
  // start streaming docker stats
  getDockerStats()
  setInterval(function () {
    var containerCount = 0
    var cpuPercentTotal = 0
    for (var container in cMetrics) {
      containerCount++
      var values = getStatsForContainer(container, metrics)
      if (!values) {
        return statsCallback(null)
      }
      values = values.map(function (v) {
        var rv = getStatsValue(v)
        return rv
      })
      var stats = {dockerId: container, image: cMetrics[container].info.image, name: cMetrics[container].info.name, value: values}
      cpuPercentTotal += values[0]
      statsCallback(stats)
    }
    statsCallback({type: 'container', name: 'count', value: containerCount})
    statsCallback({type: 'container', name: 'totalcpu', value: cpuPercentTotal})
    cMetrics = {}
  }, config.collectionInterval)
}

module.exports = dockerStatsCollector
<commit_msg>make sure values are numbers and not strings<commit_after>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence SPM for Docker is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
var stats = require('docker-stats')
var flatten = require('flat')
var through = require('through2')
var Aggregator = require('./aggregator.js')
var SpmAgent = require('spm-agent')
var config = SpmAgent.Config
var statsCallBackFuntion = null

var opts = {
  docker: null, //  here goes options for Dockerode
  events: null,  //  an instance of docker-allcontainers,
  statsinterval: 10,
  matchByName: process.env.SPM_MATCH_BY_NAME,
  matchByImage: process.env.SPM_MATCH_BY_IMAGE,
  skipByName: process.env.SPM_SKIP_BY_NAME,
  skipByImage: process.env.SPM_SKIP_BY_IMAGE
}
// holds aggregation object for each container
var cMetrics = {}
var counter = require('measured').createCollection()

function transformStatsApi1_21 (stats) {
  if (!stats.networks) {
    return stats
  }
  var result = {
      rx_bytes: 0,
      rx_packets: 0,
      rx_errors: 0,
      rx_dropped: 0,
      tx_bytes: 0,
      tx_packets: 0,
      tx_errors: 0,
      tx_dropped: 0
  }
  Object.keys(stats.networks).forEach(function aggNetworkMetrics (key) {
    Object.keys(result).forEach(function (metric) {
      result[metric] += stats.networks[key][metric]
    })
  })
  stats.network = result
  if (process.env.spmagent_logger__level === 'debug') {
    console.log('docker stats transformStatsApi1_21: ' + JSON.stringify(stats))
  }
  return stats
}

// handling different structures of docker stats
function transformStats (stats) {
  if (process.env.spmagent_logger__level === 'debug') {
    console.log('docker stats: ' + JSON.stringify(stats))
  }
  if (stats.network && stats.network.rx_bytes) {
    // API < 1.21
    return stats
  } else {
    return transformStatsApi1_21(stats)
  }
}

function processStats (chunk, enc, cb) {
  var stats = flatten(transformStats(chunk.stats))
  var metric = {}
  if (process.env.spmagent_logger__level === 'silly') {
    console.log(stats)
  }
  counter.meter('requestsPerSecond').mark()
  if (cMetrics[chunk.id] === undefined) {
    cMetrics[chunk.id] = new Aggregator()
  }
  metric.name = chunk.name
  metric.dockerId = chunk.id
  metric.image = chunk.image
  var agg = cMetrics[chunk.id]
  agg.info = metric
  metrics.forEach(function (key) {
    var value = stats[key] || 0
    if (/service_time_/i.test(key) || /wait_time_/i.test(key)) {
      // micro seconds to ms
      value = value / (1000 * 1000)
    }
    agg.update(stats['read'], key, Number(value), useDivForAggregation[key] || false)
  })
  // setTimeout (cb, 10)
  cb()
}

function getDockerStats (dockerStatsCallback) {
  var dockerStatsStream = stats(opts)
  dockerStatsStream.pipe(through.obj(processStats))
  dockerStatsStream.on('closed', function () {
    console.log('docker stats stream closed')
    // process.exit()
  })
  dockerStatsStream.once('error', function (err) {
    console.log('docker stats stream error:' + err)
    // try to reconnect
    setTimeout(function () {
      getDockerStats(dockerStatsCallback)
    }, 15000)
    try {
      dockerStatsStream.close()
    } catch (ex) {
      console.log(ex)
    }
  })
}

function getStatsForContainer (container, aggStats) {
  var agg = cMetrics[container]
  if (!agg) {
    return null
  }
  var values = []
  aggStats.forEach(function (key) {
    var metricStats = agg.get(key)
    metricStats.id = container
    values.push(metricStats)
  })
  agg.reset()
  return values
}

var cpuMetrics = [
  // CPU
  // 'cpu_stats.cpu_usage.total_usage',
  // 'cpu_stats.cpu_usage.percpu_usage.0',
  // 'cpu_stats.cpu_usage.usage_in_kernelmode',
  // 'cpu_stats.cpu_usage.usage_in_usermode',
  'cpu_stats.cpu_usage.cpu_percent',
  // 'cpu_stats.system_cpu_usage',
  // 'cpu_stats.throttling_data.periods',
  // 'cpu_stats.throttling_data.throttled_periods',
  'cpu_stats.throttling_data.throttled_time'
]

var networkMetrics = [
  // NETWORK
  'network.rx_bytes',
  'network.rx_packets',
  'network.rx_errors',
  'network.rx_dropped',
  'network.tx_bytes',
  'network.tx_packets',
  'network.tx_errors',
  'network.tx_dropped'
]

var memoryMetrics = [
  // MEMORY
  'memory_stats.usage',
  'memory_stats.limit',
  'memory_stats.failcnt',
  // 'memory_stats.max_usage',
  // 'memory_stats.active_anon',
  // 'memory_stats.active_file',
  // 'memory_stats.cache',
  // 'memory_stats.hierarchical_memory_limit',
  // 'memory_stats.inactive_anon',
  // 'memory_stats.inactive_file',
  // 'memory_stats.mapped_file',
  'memory_stats.stats.pgfault',
  // 'memory_stats.pgmajfault',
  'memory_stats.stats.pgpgin',
  'memory_stats.stats.pgpgout'
  // 'memory_stats.ss',
  // 'memory_stats.rss_huge',
  // MEMORY FAIL COUNTER

  // MEMORY LIMIT

// MEMORY TOTAL
// 'memory_stats.total_active_anon',
// 'memory_stats.total_active_file',
// 'memory_stats.total_cache',
// 'memory_stats.total_inactive_anon',
// 'memory_total_inactive_file',
// 'memory_stats.total_mapped_file',
// 'memory_stats.total_pgfault',
// 'memory_stats.total_pgmajfault',
// 'memory_stats.total_pgpgin',
// 'memory_stats.total_pgpgout',
// 'memory_stats.total_rss',
// 'memory_stats.total_rss_huge',
// 'memory_stats.total_unevictable',
// 'memory_stats.stats.total_writeback',
// 'memory_stats.unevictable',
// 'memory_stats.writeback'
]

var ioMetrics = [
  // IO STATS
  // READ
  'blkio_stats.io_service_bytes_recursive.0.value',
  // READ time
  'blkio_stats.io_service_time_recursive.0.value',
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value',
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value',
  // Write time
  'blkio_stats.io_service_time_recursive.1.value',
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value'
// 'blkio_io_service_bytes_recursive',
// 'blkio_io_serviced_recursive',
// 'blkio_io_queue_recursive',
// 'blkio_io_service_time_recursive',
// 'blkio_io_wait_time_recursive',
// 'blkio_io_merged_recursive',
// 'blkio_io_time_recursive',
// 'blkio_sectors_recursive'
]
var metrics = []
metrics = metrics.concat(cpuMetrics).concat(networkMetrics).concat(memoryMetrics).concat(ioMetrics)
var avgAggregation = {
  'cpu_stats.cpu_usage.cpu_percent': true,
  'cpu_stats.throttling_data.throttled_time': true,
  'memory_stats.usage': true,
  'memory_stats.limit': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}
var useDivForAggregation = {
  'network.rx_bytes': true,
  'network.rx_packets': true,
  'network.rx_errors': true,
  'network.rx_dropped': true,
  'network.tx_bytes': true,
  'network.tx_packets': true,
  'network.tx_errors': true,
  'network.tx_dropped': true,
  'memory_stats.failcnt': true,
  'memory_stats.stats.pgfault': true,
  'memory_stats.stats.pgpgin': true,
  'memory_stats.stats.pgpgout': true,
  'blkio_stats.io_service_bytes_recursive.0.value': true,
  // READ time
  'blkio_stats.io_service_time_recursive.0.value': true,
  // READ wait time
  'blkio_stats.io_wait_time_recursive.0.value': true,
  // WRITE
  'blkio_stats.io_service_bytes_recursive.1.value': true,
  // Write time
  'blkio_stats.io_service_time_recursive.1.value': true,
  // Write wait time
  'blkio_stats.io_wait_time_recursive.1.value': true
}

function getValueAsNum (value) {
  var rv = 0
  if (!isNaN(value)) {
    rv = value
  }
  return rv
}

function getStatsValue (metric) {
  if (avgAggregation[metric.name]) {
    return getValueAsNum(metric.mean)
  } else {
    return getValueAsNum(metric.sum)
  }
}
function dockerStatsCollector (statsCallback) {
  // start streaming docker stats
  getDockerStats()
  setInterval(function () {
    var containerCount = 0
    var cpuPercentTotal = 0
    for (var container in cMetrics) {
      containerCount++
      var values = getStatsForContainer(container, metrics)
      if (!values) {
        return statsCallback(null)
      }
      values = values.map(function (v) {
        var rv = getStatsValue(v)
        return rv
      })
      var stats = {dockerId: container, image: cMetrics[container].info.image, name: cMetrics[container].info.name, value: values}
      cpuPercentTotal += values[0]
      statsCallback(stats)
    }
    statsCallback({type: 'container', name: 'count', value: containerCount})
    statsCallback({type: 'container', name: 'totalcpu', value: cpuPercentTotal})
    cMetrics = {}
  }, config.collectionInterval)
}

module.exports = dockerStatsCollector
<|endoftext|>


<commit_before>import $ from 'jquery';
import application from 'lighty';

import { fixture, clear } from './fixtures';

import plugin from '../src/index';

describe('lighty-plugin-legacy', () => {
  beforeAll(() => {
    application.use(plugin).run();
  });

  afterEach(clear);

  describe('load events', () => {
    it('adds support for `load on window` pattern', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      application.component('.load-events', {
        'load on window': eventSpy,
      });

      application.vitalize();

      expect(eventSpy.callCount).toEqual(0);

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);

        done();
      }, 10);
    });

    it('calls handler on a component instance', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      let component;

      application.component('.load-events-context', {
        init() {
          component = this;
        },

        'load on window': eventSpy,
      }).vitalize();

      expect(eventSpy.callCount).toEqual(0);
      expect(component).toBeTruthy();

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);
        expect(eventSpy.calledOn(component)).toBe(true);

        done();
      });
    });

    it('passes an event to a handler', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      application.component('.load-events-event', {
        'load on window': eventSpy,
      }).vitalize();

      expect(eventSpy.callCount).toEqual(0);

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);
        expect(eventSpy.getCall(0).args[0] instanceof $.Event).toBe(true);

        done();
      });
    });
  });
});
<commit_msg>Fix load events specs<commit_after>import $ from 'jquery';
import application from 'lighty';

import { fixture, clear } from './fixtures';

import plugin from '../src/index';

describe('lighty-plugin-legacy', () => {
  beforeAll(() => {
    application.use(plugin).run();
  });

  afterEach(clear);

  describe('load events', () => {
    it('adds support for `load on window` pattern', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      application.component('.load-events', {
        'load on window': eventSpy,
      });

      application.vitalize();

      expect(eventSpy.callCount).toEqual(0);

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);

        done();
      }, 10);
    });

    it('calls handler on a component instance', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      let component;

      application.component('.load-events-context', {
        init() {
          component = this;
        },

        'load on window': eventSpy,
      }).vitalize();

      expect(eventSpy.callCount).toEqual(0);
      expect(component).toBeTruthy();

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);
        expect(eventSpy.calledOn(component)).toBe(true);

        done();
      }, 10);
    });

    it('passes an event to a handler', done => {
      fixture('

');

      const eventSpy = sinon.spy();

      application.component('.load-events-event', {
        'load on window': eventSpy,
      }).vitalize();

      expect(eventSpy.callCount).toEqual(0);

      setTimeout(() => {
        expect(eventSpy.callCount).toEqual(1);
        expect(eventSpy.getCall(0).args[0] instanceof $.Event).toBe(true);

        done();
      }, 10);
    });
  });
});
<|endoftext|>


<commit_before>class Filter {
    constructor(expression, colour, filters) {
        this.expression = expression;
        this.colour = colour;
        this.validExpressionVars = ['float', 'seed', 'minfloat', 'maxfloat'];
        this.filters = filters;

        this.compileExpression();
    }

    static filtrexMatch(str, reg) {
        let thisMatch = str.toString().match(reg);

        if (thisMatch !== null) return thisMatch.length;
        else return 0;
    }

    compileExpression() {
        this.func = compileExpression(this.expression, {match: Filter.filtrexMatch}, this.validExpressionVars);
    }

    onFilterColourChange(e) {
        let colourSwitch = e.target || e.srcElement;

        this.filters.setFilterColour(this, colourSwitch.value);
    }

    addToUI() {
        let parentDiv = document.querySelector('#floatFilters');

        let thisDiv = document.createElement('div');
        thisDiv.innerText = this.expression;

        let colourDiv = document.createElement('input');
        colourDiv.type = 'color';
        colourDiv.value = this.colour;
        colourDiv.style.float = 'left';
        colourDiv.style.marginRight = '10px';
        colourDiv.style.marginTop = '-3px';
        colourDiv.addEventListener('change', (e) => this.onFilterColourChange(e));
        thisDiv.appendChild(colourDiv);

        // Add remove filter btn
        let removeFilterBtn = createButton('Remove Filter', 'grey');
        removeFilterBtn.addEventListener('click', (e) => this.removeFilter(e));
        removeFilterBtn.style.marginTop = '-3px';
        removeFilterBtn.style.float = 'right';
        thisDiv.appendChild(removeFilterBtn);

        // Add line break
        let hr = document.createElement('hr');
        thisDiv.appendChild(hr);

        this.div = thisDiv;
        parentDiv.appendChild(thisDiv);
    }

    removeFilter() {
        this.filters.removeFilter(this);
    }
}

class Filters {
    constructor() {
        this.filters = [];
        this.expressionTimer = false;
    }

    getMatchColour(vars) {
        let colours = [];

        for (let filter of this.filters) {
            if (filter.func(vars) === 1) colours.push(hexToRgb(filter.colour));
        }

        if (colours.length > 0) {
            // Get the average colour between each matching filter
            let avg_colours = [0, 0, 0];

            for (let colour of colours) {
                for (let index in colour) {
                    avg_colours[index] += colour[index];
                }
            }

            for (let index in avg_colours) {
                avg_colours[index] = parseInt(avg_colours[index]/colours.length);
            }

            return rgbToHex(avg_colours);
        }
    }

    addFilter(expression, colour) {
        if (arguments.length === 0) {
            expression = document.querySelector('#float_expression_filter').value;
            colour = document.querySelector('#floatFilterColour').value;
        }

        let filter = new Filter(expression, colour, this);

        filter.addToUI();

        this.filters.push(filter);
        this.saveFilters();
    }

    tryCompile(expression) {
        new Filter(expression, '', this);
    }

    setFilterColour(filter, colour) {
        let index = this.filters.indexOf(filter);

        if (index === -1) return;

        this.filters[index].colour = colour;

        this.saveFilters();
    }

    removeFilter(filter) {
        let index = this.filters.indexOf(filter);

        if (index === -1) return;

        filter.div.parentNode.removeChild(filter.div);
        this.filters.splice(index, 1);

        this.saveFilters();
    }

    onHelpClick() {
        let filterdiv = document.querySelector('#floatFilter');

        let helpdiv = filterdiv.querySelector('#filterHelp');
        if (helpdiv) filterdiv.removeChild(helpdiv);
        else {
            // create it
            helpdiv = document.createElement('div');
            helpdiv.id = 'filterHelp';

            helpdiv.innerHTML = `

            Filters will highlight matching items with the specified colour

            Examples:

float < 0.3

Matches items with floats less than 0.3

float >= 0.112 and float < 0.2

Matches items with floats greater than or equal to 0.112 and less than 0.2

float == 0.2 or (seed > 500 and float < 0.15)

Matches items with floats of 0.2 or paint seeds greater than 500 and floats less than 0.15

match(float, "7355608") >= 1

Matches items with floats that contain at least one match of the CS bomb code

Example Match: 0.234327355608454

            Variables

float

The float value of the item

seed

The paint seed of the item

minfloat

The minimum float the skin can have (regardless of wear)

maxfloat

The maximum float the skin can have (regardless of wear)

            Functions:

match(x, regex)

Performs a regex match on 'x' and returns the amount of matches

abs(x)

Absolute value

ceil(x)

Round floating point up

floor(x)

Round floating point down

log(x)

Natural logarithm

max(a, b, c...)

Max value (variable length of args)

min(a, b, c...)

Min value (variable length of args)

random()

Random floating point from 0.0 to 1.0

round(x)

Round floating point

sqrt(x)

Square root

        `;

            filterdiv.appendChild(helpdiv);
        }
    }

    addFilterUI(parent) {
        let filterdiv = document.createElement('div');
        filterdiv.id = 'floatFilter';
        parent.appendChild(filterdiv);

        // Add separator
        let hr = document.createElement('hr');
        filterdiv.appendChild(hr);

        // Adds filters div
        let filtersdiv = document.createElement('div');
        filtersdiv.id = 'floatFilters';
        filterdiv.appendChild(filtersdiv);

        // Adds colour picker
        let colourDiv = document.createElement('input');
        colourDiv.id = 'floatFilterColour';
        colourDiv.type = 'color';
        colourDiv.value = '#354908';
        colourDiv.style.float = 'left';
        colourDiv.style.marginTop = '2px';
        filterdiv.appendChild(colourDiv);

        // Add new filter input box
        let input = document.createElement('input');
        input.id = 'float_expression_filter';
        input.classList.add('filter_search_box');
        input.placeholder = 'Add Float Highlight Filter';
        input.style.width = '350px';
        input.style.marginLeft = '10px';
        input.addEventListener('keyup', (e) => this.filterKeyPress(e));
        filterdiv.appendChild(input);

        // Add filter help link
        let helpText = document.createElement('a');
        helpText.innerText = 'ⓘ';
        helpText.style.fontSize = '18px';
        helpText.title = 'Filter Help';
        helpText.style.marginLeft = '5px';
        helpText.href = 'javascript:void(0)';
        helpText.addEventListener('click', (e) => this.onHelpClick(e));
        filterdiv.appendChild(helpText);

        // Add compile status indicator
        let status = document.createElement('div');
        status.id = 'compileStatus';
        filterdiv.appendChild(status);

        // Add new filter btn
        let addFilterBtn = createButton('Add Filter', 'green');
        addFilterBtn.addEventListener('click', (e) => this.addFilter());
        addFilterBtn.id = 'addFloatFilter';
        addFilterBtn.style.display = 'none';
        addFilterBtn.style.marginLeft = '10px';

        filterdiv.appendChild(addFilterBtn);

        // Compile error div
        let compileError = document.createElement('div');
        compileError.id = 'compileError';
        filterdiv.appendChild(compileError);

        // Add any saved filters
        this.getSavedFilters((savedFilters) => {
            for (let filter of savedFilters) {
                let newFilter = new Filter(filter.expression, filter.colour, this);
                this.filters.push(newFilter);
                newFilter.addToUI();
            }
        });
    }

    filterKeyPress() {
        if (this.expressionTimer) clearTimeout(this.expressionTimer);

        this.expressionTimer = setTimeout(() => {
            let input = document.querySelector('#float_expression_filter');
            let compileError = document.querySelector('#compileError');
            let status = document.querySelector('#compileStatus');
            let addFilterBtn = document.querySelector('#addFloatFilter');

            let expression = input.value;

            // try to compile the expression
            try {
                this.tryCompile(expression);
                status.setAttribute('error', 'false');
                status.innerText = '✓';
                compileError.innerText = '';
                addFilterBtn.style.display = '';
            }
            catch (e) {
                if (expression === '') {
                    status.innerText = '';
                    compileError.innerText = '';
                } else {
                    status.setAttribute('error', 'true');
                    compileError.innerText = e.message;
                }
                addFilterBtn.style.display = 'none';
            }
        }, 250);
    }

    getSaveKey() {
        let itemName = document.querySelector('.market_listing_nav a:nth-child(2)');

        if (itemName) return itemName.innerText + '_expressions';
    }

    getSavedFilters(cb) {
        let key = this.getSaveKey();

        if (!key) cb([]);

        let syncFilters = {};
        syncFilters[key] = [];

        let storageType = chrome.storage.sync;
        if (!storageType) storageType = chrome.storage.local;

        storageType.get(syncFilters, (items) => {
            cb(items[key]);
        });
    }

    saveFilters() {
        let key = this.getSaveKey();

        if (!key) return;

        let syncFilters = {};
        let filterArray = [];

        for (let filter of this.filters) {
            filterArray.push({expression: filter.expression, colour: filter.colour});
        }

        syncFilters[key] = filterArray;

        let storageType = chrome.storage.sync;
        if (!storageType) storageType = chrome.storage.local;

        storageType.set(syncFilters);

        // update UI
        removeButtons();
    }
}
<commit_msg>Ensures MAX_WRITE_OPERATIONS_PER_MINUTE Isn't Hit<commit_after>class Filter {
    constructor(expression, colour, filters) {
        this.expression = expression;
        this.colour = colour;
        this.validExpressionVars = ['float', 'seed', 'minfloat', 'maxfloat'];
        this.filters = filters;

        this.compileExpression();
    }

    static filtrexMatch(str, reg) {
        let thisMatch = str.toString().match(reg);

        if (thisMatch !== null) return thisMatch.length;
        else return 0;
    }

    compileExpression() {
        this.func = compileExpression(this.expression, {match: Filter.filtrexMatch}, this.validExpressionVars);
    }

    onFilterColourChange(e) {
        let colourSwitch = e.target || e.srcElement;

        this.filters.setFilterColour(this, colourSwitch.value);
    }

    addToUI() {
        let parentDiv = document.querySelector('#floatFilters');

        let thisDiv = document.createElement('div');
        thisDiv.innerText = this.expression;

        let colourDiv = document.createElement('input');
        colourDiv.type = 'color';
        colourDiv.value = this.colour;
        colourDiv.style.float = 'left';
        colourDiv.style.marginRight = '10px';
        colourDiv.style.marginTop = '-3px';
        colourDiv.addEventListener('change', (e) => this.onFilterColourChange(e));
        thisDiv.appendChild(colourDiv);

        // Add remove filter btn
        let removeFilterBtn = createButton('Remove Filter', 'grey');
        removeFilterBtn.addEventListener('click', (e) => this.removeFilter(e));
        removeFilterBtn.style.marginTop = '-3px';
        removeFilterBtn.style.float = 'right';
        thisDiv.appendChild(removeFilterBtn);

        // Add line break
        let hr = document.createElement('hr');
        thisDiv.appendChild(hr);

        this.div = thisDiv;
        parentDiv.appendChild(thisDiv);
    }

    removeFilter() {
        this.filters.removeFilter(this);
    }
}

class Filters {
    constructor() {
        this.filters = [];
        this.expressionTimer = false;
    }

    getMatchColour(vars) {
        let colours = [];

        for (let filter of this.filters) {
            if (filter.func(vars) === 1) colours.push(hexToRgb(filter.colour));
        }

        if (colours.length > 0) {
            // Get the average colour between each matching filter
            let avg_colours = [0, 0, 0];

            for (let colour of colours) {
                for (let index in colour) {
                    avg_colours[index] += colour[index];
                }
            }

            for (let index in avg_colours) {
                avg_colours[index] = parseInt(avg_colours[index]/colours.length);
            }

            return rgbToHex(avg_colours);
        }
    }

    addFilter(expression, colour) {
        if (arguments.length === 0) {
            expression = document.querySelector('#float_expression_filter').value;
            colour = document.querySelector('#floatFilterColour').value;
        }

        let filter = new Filter(expression, colour, this);

        filter.addToUI();

        this.filters.push(filter);
        this.saveFilters();
    }

    tryCompile(expression) {
        new Filter(expression, '', this);
    }

    setFilterColour(filter, colour) {
        let index = this.filters.indexOf(filter);

        if (index === -1) return;

        this.filters[index].colour = colour;

        this.saveFilters();
    }

    removeFilter(filter) {
        let index = this.filters.indexOf(filter);

        if (index === -1) return;

        filter.div.parentNode.removeChild(filter.div);
        this.filters.splice(index, 1);

        this.saveFilters();
    }

    onHelpClick() {
        let filterdiv = document.querySelector('#floatFilter');

        let helpdiv = filterdiv.querySelector('#filterHelp');
        if (helpdiv) filterdiv.removeChild(helpdiv);
        else {
            // create it
            helpdiv = document.createElement('div');
            helpdiv.id = 'filterHelp';

            helpdiv.innerHTML = `

            Filters will highlight matching items with the specified colour

            Examples:

float < 0.3

Matches items with floats less than 0.3

float >= 0.112 and float < 0.2

Matches items with floats greater than or equal to 0.112 and less than 0.2

float == 0.2 or (seed > 500 and float < 0.15)

Matches items with floats of 0.2 or paint seeds greater than 500 and floats less than 0.15

match(float, "7355608") >= 1

Matches items with floats that contain at least one match of the CS bomb code

Example Match: 0.234327355608454

            Variables

float

The float value of the item

seed

The paint seed of the item

minfloat

The minimum float the skin can have (regardless of wear)

maxfloat

The maximum float the skin can have (regardless of wear)

            Functions:

match(x, regex)

Performs a regex match on 'x' and returns the amount of matches

abs(x)

Absolute value

ceil(x)

Round floating point up

floor(x)

Round floating point down

log(x)

Natural logarithm

max(a, b, c...)

Max value (variable length of args)

min(a, b, c...)

Min value (variable length of args)

random()

Random floating point from 0.0 to 1.0

round(x)

Round floating point

sqrt(x)

Square root

        `;

            filterdiv.appendChild(helpdiv);
        }
    }

    addFilterUI(parent) {
        let filterdiv = document.createElement('div');
        filterdiv.id = 'floatFilter';
        parent.appendChild(filterdiv);

        // Add separator
        let hr = document.createElement('hr');
        filterdiv.appendChild(hr);

        // Adds filters div
        let filtersdiv = document.createElement('div');
        filtersdiv.id = 'floatFilters';
        filterdiv.appendChild(filtersdiv);

        // Adds colour picker
        let colourDiv = document.createElement('input');
        colourDiv.id = 'floatFilterColour';
        colourDiv.type = 'color';
        colourDiv.value = '#354908';
        colourDiv.style.float = 'left';
        colourDiv.style.marginTop = '2px';
        filterdiv.appendChild(colourDiv);

        // Add new filter input box
        let input = document.createElement('input');
        input.id = 'float_expression_filter';
        input.classList.add('filter_search_box');
        input.placeholder = 'Add Float Highlight Filter';
        input.style.width = '350px';
        input.style.marginLeft = '10px';
        input.addEventListener('keyup', (e) => this.filterKeyPress(e));
        filterdiv.appendChild(input);

        // Add filter help link
        let helpText = document.createElement('a');
        helpText.innerText = 'ⓘ';
        helpText.style.fontSize = '18px';
        helpText.title = 'Filter Help';
        helpText.style.marginLeft = '5px';
        helpText.href = 'javascript:void(0)';
        helpText.addEventListener('click', (e) => this.onHelpClick(e));
        filterdiv.appendChild(helpText);

        // Add compile status indicator
        let status = document.createElement('div');
        status.id = 'compileStatus';
        filterdiv.appendChild(status);

        // Add new filter btn
        let addFilterBtn = createButton('Add Filter', 'green');
        addFilterBtn.addEventListener('click', (e) => this.addFilter());
        addFilterBtn.id = 'addFloatFilter';
        addFilterBtn.style.display = 'none';
        addFilterBtn.style.marginLeft = '10px';

        filterdiv.appendChild(addFilterBtn);

        // Compile error div
        let compileError = document.createElement('div');
        compileError.id = 'compileError';
        filterdiv.appendChild(compileError);

        // Add any saved filters
        this.getSavedFilters((savedFilters) => {
            for (let filter of savedFilters) {
                let newFilter = new Filter(filter.expression, filter.colour, this);
                this.filters.push(newFilter);
                newFilter.addToUI();
            }
        });
    }

    filterKeyPress() {
        if (this.expressionTimer) clearTimeout(this.expressionTimer);

        this.expressionTimer = setTimeout(() => {
            let input = document.querySelector('#float_expression_filter');
            let compileError = document.querySelector('#compileError');
            let status = document.querySelector('#compileStatus');
            let addFilterBtn = document.querySelector('#addFloatFilter');

            let expression = input.value;

            // try to compile the expression
            try {
                this.tryCompile(expression);
                status.setAttribute('error', 'false');
                status.innerText = '✓';
                compileError.innerText = '';
                addFilterBtn.style.display = '';
            }
            catch (e) {
                if (expression === '') {
                    status.innerText = '';
                    compileError.innerText = '';
                } else {
                    status.setAttribute('error', 'true');
                    compileError.innerText = e.message;
                }
                addFilterBtn.style.display = 'none';
            }
        }, 250);
    }

    getSaveKey() {
        let itemName = document.querySelector('.market_listing_nav a:nth-child(2)');

        if (itemName) return itemName.innerText + '_expressions';
    }

    getSavedFilters(cb) {
        let key = this.getSaveKey();

        if (!key) cb([]);

        let syncFilters = {};
        syncFilters[key] = [];

        let storageType = chrome.storage.sync;
        if (!storageType) storageType = chrome.storage.local;

        storageType.get(syncFilters, (items) => {
            cb(items[key]);
        });
    }

    /**
     * Ensures we don't hit MAX_WRITE_OPERATIONS_PER_MINUTE
     */
    saveFilters() {
        clearTimeout(this.saveTimeout);

        this.saveTimeout = setTimeout(() => this._saveFilters(), 750);
    }

    _saveFilters() {
        let key = this.getSaveKey();

        if (!key) return;

        let syncFilters = {};
        let filterArray = [];

        for (let filter of this.filters) {
            filterArray.push({expression: filter.expression, colour: filter.colour});
        }

        syncFilters[key] = filterArray;

        let storageType = chrome.storage.sync;
        if (!storageType) storageType = chrome.storage.local;

        storageType.set(syncFilters);

        // update UI
        removeButtons();
    }
}
<|endoftext|>


<commit_before>(function($) {
  $.declare('floater', {
    defaults: {
      topPadding: 0,
      stopPoint: -1,
      startPoint: -1,
      relative: false,
      offsetX: 0,
      offsetY: 0,
      debug: false
    },

    init: function() {
      this.enabled = true;
      this.resetStyles = {
        position: this.el.css('position'),
        top: this.el.css('top'),
        left: this.el.css('left'),
        width: this.el.css('width')
      };

      var offset = this.el.offset();
      this.topPadding = parseInt(this.topPadding, 10);
      this.startPoint = this.startPoint == -1 ? (offset.top - this.topPadding) : this.startPoint;
      this.height = this.el.outerHeight(true);

      if (typeof this.stopPoint == 'object' && this.stopPoint.length) {
        this.stopPoint = this.stopPoint.offset().top;
      }

      this.floating = false;
      $(window).on('scroll', this.proxy(this.onScroll));
      this.onScroll();
      if (this.debug) {
        this.showDebug();
      }
    },

    setStartPoint: function(point) {
      this.startPoint = point;
    },

    setStopPoint: function(point) {
      this.stopPoint = point;
    },

    showDebug: function() {
      var showLine = function(top) {
        $('<div/>').css({
          position: 'absolute',
          height: '1px',
          width: '100%',
          background: 'red',
          top: top
        }).appendTo('body');
      };
      showLine(this.startPoint);
      showLine(this.stopPoint);
    },

    createPlaceholder: function() {
      var classes = this.el[0].className || '';
      return $('<div/>')
        .addClass('floater-placeholder ' + classes)
        .css({
          width: this.el.css('width'),
          height: this.el.css('height'),
          visibility: 'hidden'
        });
    },

    startFloat: function() {
      if (this.floating) {
        return;
      }
      this.floating = true;
      var offset = this.el.offset();
      if (!this.el.prev().hasClass('floater-placeholder')) {
        this.el.before(this.createPlaceholder());
      }
      this.el.css({
        position: 'fixed',
        top: this.topPadding + 'px',
        left: offset.left + this.offsetX,
        width: this.el.css('width')
      });
      this.emit('floatStart');
    },

    stopFloat: function(y) {
      if (!this.floating) {
        return;
      }
      this.floating = false;
      this.el.prev().remove();
      this.el.css({
        position: '',
        top: '',
        left: '',
        width: ''
      });
      this.emit('floatStop');
    },

    freezeFloat: function(y) {
      if (!this.floating) {
        return;
      }
      this.floating = false;
      this.el.css({
        position: 'absolute',
        top: y,
        left: '',
        width: this.el.css('width')
      });
      this.emit('floatStop');

    },

    onScroll: function(e) {
      if (!this.enabled) {
        return;
      }
      var scrollY = $(window).scrollTop();
      if (scrollY > this.startPoint) {
        if (this.stopPoint != -1 && (scrollY + this.height + this.topPadding) > this.stopPoint) {
          if (this.floating) {
            this.freezeFloat(this.stopPoint - this.height);
          }
        } else if (!this.floating) {
          this.startFloat();
        }
      } else if (this.floating && scrollY < this.startPoint) { //top of screen
        this.stopFloat();
      }
    },

    on: function() {
      this.enabled = true;
      this.onScroll();
    },

    off: function() {
      this.stopFloat();
      this.enabled = false;
    }
  });

})(window.jQuery || window.Zepto);
<commit_msg>[lib] update debug lines on set<commit_after>(function($) {
  $.declare('floater', {
    defaults: {
      topPadding: 0,
      stopPoint: -1,
      startPoint: -1,
      relative: false,
      offsetX: 0,
      offsetY: 0,
      debug: false
    },

    init: function() {
      this.enabled = true;
      this.resetStyles = {
        position: this.el.css('position'),
        top: this.el.css('top'),
        left: this.el.css('left'),
        width: this.el.css('width')
      };

      var offset = this.el.offset();
      this.topPadding = parseInt(this.topPadding, 10);
      this.startPoint = this.startPoint == -1 ? (offset.top - this.topPadding) : this.startPoint;
      this.height = this.el.outerHeight(true);

      if (typeof this.stopPoint == 'object' && this.stopPoint.length) {
        this.stopPoint = this.stopPoint.offset().top;
      }

      this.floating = false;
      $(window).on('scroll', this.proxy(this.onScroll));
      this.onScroll();
      if (this.debug) {
        this.showDebug();
      }
    },

    setStartPoint: function(point) {
      this.startPoint = point;
      if (this.debug) {
        this.showDebug();
      }
    },

    setStopPoint: function(point) {
      this.stopPoint = point;
      if (this.debug) {
        this.showDebug();
      }
    },

    showDebug: function() {
      $('.floater-debug').remove();
      var showLine = function(top) {
        $('<div/>').css({
          position: 'absolute',
          height: '1px',
          width: '100%',
          background: 'red',
          top: top
        })
        .addClass('floater-debug')
        .appendTo('body');
      };
      showLine(this.startPoint);
      showLine(this.stopPoint);
    },

    createPlaceholder: function() {
      var classes = this.el[0].className || '';
      return $('<div/>')
        .addClass('floater-placeholder ' + classes)
        .css({
          width: this.el.css('width'),
          height: this.el.css('height'),
          visibility: 'hidden'
        });
    },

    startFloat: function() {
      if (this.floating) {
        return;
      }
      this.floating = true;
      var offset = this.el.offset();
      if (!this.el.prev().hasClass('floater-placeholder')) {
        this.el.before(this.createPlaceholder());
      }
      this.el.css({
        position: 'fixed',
        top: this.topPadding + 'px',
        left: offset.left + this.offsetX,
        width: this.el.css('width')
      });
      this.emit('floatStart');
    },

    stopFloat: function(y) {
      if (!this.floating) {
        return;
      }
      this.floating = false;
      this.el.prev().remove();
      this.el.css({
        position: '',
        top: '',
        left: '',
        width: ''
      });
      this.emit('floatStop');
    },

    freezeFloat: function(y) {
      if (!this.floating) {
        return;
      }
      this.floating = false;
      this.el.css({
        position: 'absolute',
        top: y,
        left: '',
        width: this.el.css('width')
      });
      this.emit('floatStop');

    },

    onScroll: function(e) {
      if (!this.enabled) {
        return;
      }
      var scrollY = $(window).scrollTop();
      if (scrollY > this.startPoint) {
        if (this.stopPoint != -1 && (scrollY + this.height + this.topPadding) > this.stopPoint) {
          if (this.floating) {
            this.freezeFloat(this.stopPoint - this.height);
          }
        } else if (!this.floating) {
          this.startFloat();
        }
      } else if (this.floating && scrollY < this.startPoint) { //top of screen
        this.stopFloat();
      }
    },

    on: function() {
      this.enabled = true;
      this.onScroll();
    },

    off: function() {
      this.stopFloat();
      this.enabled = false;
    }
  });

})(window.jQuery || window.Zepto);
<|endoftext|>