<commit_before>/*
 * Package Configuration Extension
 *
 * Example:
 *
 * System.packages = {
 *   jquery: {
 *     main: 'index.js', // when not set, package name is requested directly
 *     format: 'amd',
 *     defaultExtension: 'js',
 *     meta: {
 *       '*.ts': {
 *         loader: 'typescript'
 *       },
 *       'vendor/sizzle.js': {
 *         format: 'global'
 *       }
 *     },
 *     map: {
 *        // map internal require('sizzle') to local require('./vendor/sizzle')
 *        sizzle: './vendor/sizzle.js',
 *        // map any internal or external require of 'jquery/vendor/another' to 'another/index.js'
 *        './vendor/another.js': './another/index.js',
 *        // test.js / test -> lib/test.js
 *        './test.js': './lib/test.js',
 *     },
 *     env: {
 *       'browser': {
 *         main: 'browser.js'
 *       }
 *     }
 *   }
 * };
 *
 * Then:
 *   import 'jquery'                       -> jquery/index.js
 *   import 'jquery/submodule'             -> jquery/submodule.js
 *   import 'jquery/submodule.ts'          -> jquery/submodule.ts loaded as typescript
 *   import 'jquery/vendor/another'        -> another/index.js
 *
 * Detailed Behaviours
 * - main is the only property where a leading "./" can be added optionally
 * - map and defaultExtension are applied to the main
 * - defaultExtension adds the extension only if no other extension is present
 * - defaultJSExtensions applies after map when defaultExtension is not set
 * - if a meta value is available for a module, map and defaultExtension are skipped
 * - like global map, package map also applies to subpaths (sizzle/x, ./vendor/another/sub)
 *
 * In addition, the following meta properties will be allowed to be package
 * -relative as well in the package meta config:
 *
 *   - loader
 *   - alias
 *
 */
(function() {

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);
      this.packages = {};
    };
  });

  function getPackage(name) {
    for (var p in this.packages) {
      if (name.substr(0, p.length) === p && (name.length === p.length || name[p.length] === '/'))
        return p;
    }
  }

  function getPackageConfig(loader, pkgName) {
    var pkgConfig = loader.packages[pkgName];

    if (!pkgConfig.env)
      return Promise.resolve(pkgConfig);

    // check environment conditions
    // default environment condition is '@env' in package or '@system-env' globally
    return loader['import'](pkgConfig.map['@env'] || '@system-env', pkgName)
    .then(function(env) {
      // derived config object
      var pkg = {};
      for (var p in pkgConfig)
        if (p !== 'map' & p !== 'env')
          pkg[p] = pkgConfig[p];

      pkg.map = {};
      for (var p in pkgConfig.map)
        pkg.map[p] = pkgConfig.map[p];

      for (var e in pkgConfig.env) {
        if (env[e]) {
          var envConfig = pkgConfig.env[e];
          if (envConfig.main)
            pkg.main = envConfig.main;
          for (var m in envConfig.map)
            pkg.map[m] = envConfig.map[m];
        }
      }

      // store the derived environment config so we have this cached for next time
      loader.packages[pkgName] = pkg;

      return pkg;
    });
  }

  function applyMap(map, name) {
    var bestMatch, bestMatchLength = 0;

    for (var p in map) {
      if (name.substr(0, p.length) == p && (name.length == p.length || name[p.length] == '/')) {
        var curMatchLength = p.split('/').length;
        if (curMatchLength <= bestMatchLength)
          continue;
        bestMatch = p;
        bestMatchLength = curMatchLength;
      }
    }
    if (bestMatch)
      return map[bestMatch] + name.substr(bestMatch.length);
  }

  SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;

  hook('normalize', function(normalize) {
    return function(name, parentName) {
      // apply contextual package map first
      if (parentName) {
        var parentPackage = getPackage.call(this, parentName) ||
            this.defaultJSExtensions && parentName.substr(parentName.length - 3, 3) == '.js' &&
            getPackage.call(this, parentName.substr(0, parentName.length - 3));
      }

      if (parentPackage && name[0] !== '.') {
        var parentMap = this.packages[parentPackage].map;
        if (parentMap) {
          name = applyMap(parentMap, name) || name;

          // relative maps are package-relative
          if (name[0] === '.')
            parentName = parentPackage + '/';
        }
      }

      var defaultJSExtension = this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';

      // apply global map, relative normalization
      var normalized = normalize.call(this, name, parentName);

      // undo defaultJSExtension
      if (normalized.substr(normalized.length - 3, 3) != '.js')
        defaultJSExtension = false;
      if (defaultJSExtension)
        normalized = normalized.substr(0, normalized.length - 3);

      // check if we are inside a package
      var pkgName = getPackage.call(this, normalized);

      var loader = this;

      if (pkgName) {
        return getPackageConfig(this, pkgName)
        .then(function(pkg) {
          // main
          if (pkgName === normalized && pkg.main)
            normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);

          if (normalized.substr(pkgName.length) == '/')
            return normalized;

          // defaultExtension & defaultJSExtension
          // if we have meta for this package, don't do defaultExtensions
          var defaultExtension = '';
          if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) {
            // apply defaultExtension

            if ('defaultExtension' in pkg) {
              if (pkg.defaultExtension !== false && normalized.split('/').pop().indexOf('.') == -1)
                defaultExtension = '.' + pkg.defaultExtension;
            }
            // apply defaultJSExtensions if defaultExtension not set
            else if (defaultJSExtension) {
              defaultExtension = '.js';
            }
          }

          // apply submap checking without then with defaultExtension
          var subPath = '.' + normalized.substr(pkgName.length);
          var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension);
          if (mapped)
            normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : normalize.call(loader, mapped);
          else
            normalized += defaultExtension;

          return normalized;
        });
      }

      // add back defaultJSExtension if not a package
      if (defaultJSExtension)
        normalized += '.js';

      return normalized;
    };
  });

  hook('locate', function(locate) {
    return function(load) {
      var loader = this;
      return Promise.resolve(locate.call(this, load))
      .then(function(address) {
        var pkgName = getPackage.call(loader, load.name);
        if (pkgName) {
          var pkg = loader.packages[pkgName];

          // format
          if (pkg.format)
            load.metadata.format = load.metadata.format || pkg.format;

          // loader
          if (pkg.loader)
            load.metadata.loader = load.metadata.loader || pkg.loader;

          if (pkg.meta) {
            // wildcard meta
            var meta = {};
            var bestDepth = 0;
            var wildcardIndex;
            for (var module in pkg.meta) {
              wildcardIndex = module.indexOf('*');
              if (wildcardIndex === -1)
                continue;
              if (module.substr(0, wildcardIndex) === load.name.substr(0, wildcardIndex)
                  && module.substr(wildcardIndex + 1) === load.name.substr(load.name.length - module.length + wildcardIndex + 1)) {
                var depth = module.split('/').length;
                if (depth > bestDepth)
                  bestDetph = depth;
                extend(meta, pkg.meta[module], bestDepth != depth);
              }
            }
            // exact meta
            var exactMeta = pkg.meta[load.name.substr(pkgName.length + 1)];
            if (exactMeta)
              extend(meta, exactMeta);

            // allow alias and loader to be package-relative
            if (meta.alias && meta.alias.substr(0, 2) == './')
              meta.alias = pkgName + meta.alias.substr(1);
            if (meta.loader && meta.loader.substr(0, 2) == './')
              meta.loader = pkgName + meta.loader.substr(1);

            extend(load.metadata, meta);
          }
        }

        return address;
      });
    };
  });

})();<commit_msg>package extension fix<commit_after>/*
 * Package Configuration Extension
 *
 * Example:
 *
 * System.packages = {
 *   jquery: {
 *     main: 'index.js', // when not set, package name is requested directly
 *     format: 'amd',
 *     defaultExtension: 'js',
 *     meta: {
 *       '*.ts': {
 *         loader: 'typescript'
 *       },
 *       'vendor/sizzle.js': {
 *         format: 'global'
 *       }
 *     },
 *     map: {
 *        // map internal require('sizzle') to local require('./vendor/sizzle')
 *        sizzle: './vendor/sizzle.js',
 *        // map any internal or external require of 'jquery/vendor/another' to 'another/index.js'
 *        './vendor/another.js': './another/index.js',
 *        // test.js / test -> lib/test.js
 *        './test.js': './lib/test.js',
 *     },
 *     env: {
 *       'browser': {
 *         main: 'browser.js'
 *       }
 *     }
 *   }
 * };
 *
 * Then:
 *   import 'jquery'                       -> jquery/index.js
 *   import 'jquery/submodule'             -> jquery/submodule.js
 *   import 'jquery/submodule.ts'          -> jquery/submodule.ts loaded as typescript
 *   import 'jquery/vendor/another'        -> another/index.js
 *
 * Detailed Behaviours
 * - main is the only property where a leading "./" can be added optionally
 * - map and defaultExtension are applied to the main
 * - defaultExtension adds the extension only if no other extension is present
 * - defaultJSExtensions applies after map when defaultExtension is not set
 * - if a meta value is available for a module, map and defaultExtension are skipped
 * - like global map, package map also applies to subpaths (sizzle/x, ./vendor/another/sub)
 *
 * In addition, the following meta properties will be allowed to be package
 * -relative as well in the package meta config:
 *
 *   - loader
 *   - alias
 *
 */
(function() {

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);
      this.packages = {};
    };
  });

  function getPackage(name) {
    for (var p in this.packages) {
      if (name.substr(0, p.length) === p && (name.length === p.length || name[p.length] === '/'))
        return p;
    }
  }

  function getPackageConfig(loader, pkgName) {
    var pkgConfig = loader.packages[pkgName];

    if (!pkgConfig.env)
      return Promise.resolve(pkgConfig);

    // check environment conditions
    // default environment condition is '@env' in package or '@system-env' globally
    return loader['import'](pkgConfig.map['@env'] || '@system-env', pkgName)
    .then(function(env) {
      // derived config object
      var pkg = {};
      for (var p in pkgConfig)
        if (p !== 'map' & p !== 'env')
          pkg[p] = pkgConfig[p];

      pkg.map = {};
      for (var p in pkgConfig.map)
        pkg.map[p] = pkgConfig.map[p];

      for (var e in pkgConfig.env) {
        if (env[e]) {
          var envConfig = pkgConfig.env[e];
          if (envConfig.main)
            pkg.main = envConfig.main;
          for (var m in envConfig.map)
            pkg.map[m] = envConfig.map[m];
        }
      }

      // store the derived environment config so we have this cached for next time
      loader.packages[pkgName] = pkg;

      return pkg;
    });
  }

  function applyMap(map, name) {
    var bestMatch, bestMatchLength = 0;

    for (var p in map) {
      if (name.substr(0, p.length) == p && (name.length == p.length || name[p.length] == '/')) {
        var curMatchLength = p.split('/').length;
        if (curMatchLength <= bestMatchLength)
          continue;
        bestMatch = p;
        bestMatchLength = curMatchLength;
      }
    }
    if (bestMatch)
      return map[bestMatch] + name.substr(bestMatch.length);
  }

  SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;

  hook('normalize', function(normalize) {
    return function(name, parentName) {
      // apply contextual package map first
      if (parentName) {
        var parentPackage = getPackage.call(this, parentName) ||
            this.defaultJSExtensions && parentName.substr(parentName.length - 3, 3) == '.js' &&
            getPackage.call(this, parentName.substr(0, parentName.length - 3));
      }

      if (parentPackage && name[0] !== '.') {
        var parentMap = this.packages[parentPackage].map;
        if (parentMap) {
          name = applyMap(parentMap, name) || name;

          // relative maps are package-relative
          if (name[0] === '.')
            parentName = parentPackage + '/';
        }
      }

      var defaultJSExtension = this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';

      // apply global map, relative normalization
      var normalized = normalize.call(this, name, parentName);

      // undo defaultJSExtension
      if (normalized.substr(normalized.length - 3, 3) != '.js')
        defaultJSExtension = false;
      if (defaultJSExtension)
        normalized = normalized.substr(0, normalized.length - 3);

      // check if we are inside a package
      var pkgName = getPackage.call(this, normalized);

      var loader = this;

      if (pkgName) {
        return getPackageConfig(this, pkgName)
        .then(function(pkg) {
          // main
          if (pkgName === normalized && pkg.main)
            normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);

          if (normalized.substr(pkgName.length) == '/')
            return normalized;

          // defaultExtension & defaultJSExtension
          // if we have meta for this package, don't do defaultExtensions
          var defaultExtension = '';
          if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) {
            // apply defaultExtension

            if ('defaultExtension' in pkg) {
              if (pkg.defaultExtension !== false && normalized.split('/').pop().lastIndexOf('.') == -1)
                defaultExtension = '.' + pkg.defaultExtension;
            }
            // apply defaultJSExtensions if defaultExtension not set
            else if (defaultJSExtension) {
              defaultExtension = '.js';
            }
          }

          // apply submap checking without then with defaultExtension
          var subPath = '.' + normalized.substr(pkgName.length);
          var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension);
          if (mapped)
            normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : normalize.call(loader, mapped);
          else
            normalized += defaultExtension;

          return normalized;
        });
      }

      // add back defaultJSExtension if not a package
      if (defaultJSExtension)
        normalized += '.js';

      return normalized;
    };
  });

  hook('locate', function(locate) {
    return function(load) {
      var loader = this;
      return Promise.resolve(locate.call(this, load))
      .then(function(address) {
        var pkgName = getPackage.call(loader, load.name);
        if (pkgName) {
          var pkg = loader.packages[pkgName];

          // format
          if (pkg.format)
            load.metadata.format = load.metadata.format || pkg.format;

          // loader
          if (pkg.loader)
            load.metadata.loader = load.metadata.loader || pkg.loader;

          if (pkg.meta) {
            // wildcard meta
            var meta = {};
            var bestDepth = 0;
            var wildcardIndex;
            for (var module in pkg.meta) {
              wildcardIndex = module.indexOf('*');
              if (wildcardIndex === -1)
                continue;
              if (module.substr(0, wildcardIndex) === load.name.substr(0, wildcardIndex)
                  && module.substr(wildcardIndex + 1) === load.name.substr(load.name.length - module.length + wildcardIndex + 1)) {
                var depth = module.split('/').length;
                if (depth > bestDepth)
                  bestDetph = depth;
                extend(meta, pkg.meta[module], bestDepth != depth);
              }
            }
            // exact meta
            var exactMeta = pkg.meta[load.name.substr(pkgName.length + 1)];
            if (exactMeta)
              extend(meta, exactMeta);

            // allow alias and loader to be package-relative
            if (meta.alias && meta.alias.substr(0, 2) == './')
              meta.alias = pkgName + meta.alias.substr(1);
            if (meta.loader && meta.loader.substr(0, 2) == './')
              meta.loader = pkgName + meta.loader.substr(1);

            extend(load.metadata, meta);
          }
        }

        return address;
      });
    };
  });

})();<|endoftext|>


<commit_before>/*
 * Package Configuration Extension
 *
 * Creates new `System.packages` configuration function.
 * Which in turn populates base-level configs.
 * Also adds support for package mains.
 *
 * Example:
 *
 * System.packages({
 *   jquery: {
 *     main: 'index.js',
 *     format: 'amd',
 *     defaultJSExtension: true,
 *     meta: {
 *       'vendor/sizzle.js': {
 *         format: 'global'
 *       }
 *     },
 *     map: {
 *       // map internal require('sizzle') to local require('./vendor/sizzle')
 *       sizzle: './vendor/sizzle.js',
 *
 *       // map external require of 'jquery/vendor/another.js' to 'another/index.js'
 *       './vendor/another.js': 'another/index.js'
 *     }
 *   }
 * });
 *
 * Is equivalent to:
 *
 * System.config({
 *   meta: {
 *     'jquery/*': {
 *       format: 'amd',
 *     }
 *     'jquery/vendor/sizzle.js': {
 *       format: 'global'
 *     }
 *   },
 *   map: {
 *     'jquery/vendor/another.js': 'another/index.js'
 *     jquery: {
 *       sizzle: 'jquery/vendor/sizzle.js'
 *     }
 *   }
 * });
 *
 * With normalization hooks providing main and defaultExtension support
 * so that:
 *   import 'jquery' => import 'jquery/index.js'
 *   import 'jquery/module' => import 'jquery/module.js'
 *
 */
(function() {

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);
      this.packageMains = {};
      this.packageDefaultJSExtensions = {};
    };
  });

  hook('normalize', function(normalize) {
    return function(name, parentName, parentAddress) {
      var loader = this;
      return normalize.call(loader, name, parentName, parentAddress)
      .then(function(normalized) {
        // main
        if (loader.packageMains[normalized])
          normalized = normalized + '/' + loader.packageMains[normalized];

        // defaultJSExtension
        if (normalized.split('/').pop().indexOf('.') == -1) {
          for (var d in loader.packageDefaultExtensions) {
            if (normalized.substr(0, d.length + 1) == d + '/') {
              normalized += '.js';
              break;
            }
          }
        }
        return normalized;
      });
    };
  });

  function extend(a, b) {
    a = a || {};
    for (var p in b)
      a[b] = b[p];
    return a;
  }

  SystemJSLoader.prototype.packages = function(packages) {
    var loader = this;
    for (var p in packages) {
      var pkgCfg = packages[p];

      // main
      var main = pkgCfg.main;
      if (main)
        loader.packageMains[p] = main.substr(0, 2) == './' ? main.substr(2) : main;

      // defaultJSExtension
      if (pkgCfg.defaultJSExtension)
        loader.packageDefaultJSExtensions[p] = true;

      // format
      if (pkgCfg.format)
        loader.meta[p + '/*'] = extend(loader.meta[p + '/*'], { format: pkgCfg.format });

      // meta
      for (var m in pkgCfg.meta)
        loader.meta[p + '/' + m] = extend(loader.meta[p + '/' + m], pkgCfg.meta[m]);

      // map
      for (var m in pkgCfg.map) {
        var target = pkgCfg.map[m];
        if (target.substr(0, 2) == './')
          target = p + target.substr(1);

        // package-relative base map
        if (m.substr(0, 2) == './') {
          loader.map[p + m.substr(1)] = target;
        }

        // package-contextual map
        else {
          loader.map[p] = loader.map[p] || {};
          loader.map[p][m] = target;
        }
      }
    }
  };

})();<commit_msg>plugin and alias as package-relative<commit_after>/*
 * Package Configuration Extension
 *
 * Creates new `System.packages` configuration function.
 * Which in turn populates base-level configs.
 * Also adds support for package mains.
 *
 * Example:
 *
 * System.packages({
 *   jquery: {
 *     main: 'index.js',
 *     format: 'amd',
 *     defaultJSExtension: true,
 *     meta: {
 *       'vendor/sizzle.js': {
 *         format: 'global'
 *       }
 *     },
 *     map: {
 *       // map internal require('sizzle') to local require('./vendor/sizzle')
 *       sizzle: './vendor/sizzle.js',
 *
 *       // map external require of 'jquery/vendor/another.js' to 'another/index.js'
 *       './vendor/another.js': 'another/index.js'
 *     }
 *   }
 * });
 *
 * Is equivalent to:
 *
 * System.config({
 *   meta: {
 *     'jquery/*': {
 *       format: 'amd',
 *     }
 *     'jquery/vendor/sizzle.js': {
 *       format: 'global'
 *     }
 *   },
 *   map: {
 *     'jquery/vendor/another.js': 'another/index.js'
 *     jquery: {
 *       sizzle: 'jquery/vendor/sizzle.js'
 *     }
 *   }
 * });
 *
 * With normalization hooks providing main and defaultExtension support
 * so that:
 *   import 'jquery' => import 'jquery/index.js'
 *   import 'jquery/module' => import 'jquery/module.js'
 *
 * In addition, the following meta properties will be allowed to be package
 * -relative as well in the package meta config:
 *
 *   - plugin
 *   - alias
 *
 */
(function() {

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);
      this.packageMains = {};
      this.packageDefaultJSExtensions = {};
    };
  });

  hook('normalize', function(normalize) {
    return function(name, parentName, parentAddress) {
      var loader = this;
      return normalize.call(loader, name, parentName, parentAddress)
      .then(function(normalized) {
        // main
        if (loader.packageMains[normalized])
          normalized = normalized + '/' + loader.packageMains[normalized];

        // defaultJSExtension
        if (normalized.split('/').pop().indexOf('.') == -1) {
          for (var d in loader.packageDefaultExtensions) {
            if (normalized.substr(0, d.length + 1) == d + '/') {
              normalized += '.js';
              break;
            }
          }
        }
        return normalized;
      });
    };
  });

  SystemJSLoader.prototype.packages = function(packages) {
    var loader = this;
    for (var p in packages) {
      var pkgCfg = packages[p];

      // main
      var main = pkgCfg.main;
      if (main)
        loader.packageMains[p] = main.substr(0, 2) == './' ? main.substr(2) : main;

      // defaultJSExtension
      if (pkgCfg.defaultJSExtension)
        loader.packageDefaultJSExtensions[p] = true;

      // format
      if (pkgCfg.format) {
        var formatMeta = loader.meta[p + '/*'] || {};
        formatMeta.format = pkgCfg.format;
        loader.meta[p + '/*'] = formatMeta;
      }

      // meta
      for (var m in pkgCfg.meta) {
        var meta = loader.meta[p + '/' + m] || {};
        var pkgMeta = pkgCfg.meta[m];
        for (var p in pkgMeta) {
          // plugin and alias can be package-relative
          if ((p === 'plugin' || p === 'alias')
              && pkgMeta[p].substr(0, 2) == './')
            meta[p] = p + pkgMeta[p].substr(1);
          else
            meta[p] = pkgMeta[p];
        }
        loader.meta[p + '/' + m] = meta;
      }

      // map
      for (var m in pkgCfg.map) {
        var target = pkgCfg.map[m];
        if (target.substr(0, 2) == './')
          target = p + target.substr(1);

        // package-relative base map
        if (m.substr(0, 2) == './') {
          loader.map[p + m.substr(1)] = target;
        }

        // package-contextual map
        else {
          loader.map[p] = loader.map[p] || {};
          loader.map[p][m] = target;
        }
      }
    }
  };

})();<|endoftext|>


<commit_before>"use strict";

var fs = require('fs');
var gm = require('gm');
var path = require('path');
var async = require('async');

var options = {
  type: 'jpg',
  size: 1024,
  density: 600,
  outputdir: null,
  outputname: null,
  page: null
};

var Pdf2Img = function() {};

Pdf2Img.prototype.setOptions = function(opts) {
  options.type = opts.type || options.type;
  options.size = opts.size || options.size;
  options.density = opts.density || options.density;
  options.outputdir = opts.outputdir || options.outputdir;
  options.outputname = opts.outputname || options.outputname;
  options.page = opts.page || options.page;
};

Pdf2Img.prototype.convert = function(input, callbackreturn) {
  // Make sure it has correct extension
  if (path.extname(path.basename(input)) != '.pdf') {
    return callbackreturn({
      result: 'error',
      message: 'Unsupported file type.'
    });
  }

  // Check if input file exists
  if (!isFileExists(input)) {
    return callbackreturn({
      result: 'error',
      message: 'Input file not found.'
    });
  }

  var stdout = [];
  var output = path.basename(input, path.extname(path.basename(input)));

  // Set output dir
  if (options.outputdir) {
    options.outputdir = options.outputdir + path.sep;
  } else {
    options.outputdir = output + path.sep;
  }

  // Create output dir if it doesn't exists
  if (!isDirExists(options.outputdir)) {
    fs.mkdirSync(options.outputdir);
  }

  // Set output name
  if (options.outputname) {
    options.outputname = options.outputname;
  } else {
    options.outputname = output;
  }

  async.waterfall([
    // Get pages count
        function (callback) {
             gm(input).identify("%p ", function (err, value) {
                var pageCount = String(value).split(' ');

                if (!pageCount.length) {
                    callback({
                        result: 'error',
                        message: 'Invalid page number.'
                    }, null);
                } else {
                    // Convert selected page
                    if (options.page !== null) {
                        if (options.page < pageCount.length) {
                            callback(null, [options.page]);
                        } else {
                            callback({
                                result: 'error',
                                message: 'Invalid page number.'
                            }, null);
                        }
                    } else  {
                        callback(null, pageCount);
                    }
                }

            })

        },

    // Convert pdf file
    function(pages, callback) {
      // Use eachSeries to make sure that conversion has done page by page
      async.eachSeries(pages, function(page, callbackmap) {
        var inputStream = fs.createReadStream(input);
        var outputFile = options.outputdir + options.outputname + '_' + page + '.' + options.type;

        convertPdf2Img(inputStream, outputFile, parseInt(page), function(error, result) {
          if (error) {
            return callbackmap(error);
          }

          stdout.push(result);
          return callbackmap(error, result);
        });
      }, function(e) {
        if (e) callback(e);

        return callback(null, {
          result: 'success',
          message: stdout
        });
      });
    }
  ], callbackreturn);
};

var convertPdf2Img = function(input, output, page, callback) {
  if (input.path) {
    var filepath = input.path;
  } else {
    return callback({
      result: 'error',
      message: 'Invalid input file path.'
    }, null);
  }

  var filename = filepath + '[' + (page - 1) + ']';

  gm(input, filename)
    .density(options.density, options.density)
    .resize(options.size)
    .quality(100)
    .write(output, function(err) {
      if (err) {
        return callback({
          result: 'error',
          message: 'Can not write output file.'
        }, null);
      }

      if (!(fs.statSync(output)['size'] / 1000)) {
        return callback({
          result: 'error',
          message: 'Zero sized output image detected.'
        }, null);
      }

      var results = {
        page: page,
        name: path.basename(output),
        size: fs.statSync(output)['size'] / 1000.0,
        path: output
      };

      return callback(null, results);
    });
};

// Check if directory is exists
var isDirExists = function(path) {
  try {
    return fs.statSync(path).isDirectory();
  } catch (e) {
    return false;
  }
}

// Check if file is exists
var isFileExists = function(path) {
  try {
    return fs.statSync(path).isFile();
  } catch (e) {
    return false;
  }
}

module.exports = new Pdf2Img;
<commit_msg>fix last page bug<commit_after>"use strict";

var fs = require('fs');
var gm = require('gm');
var path = require('path');
var async = require('async');

var options = {
  type: 'jpg',
  size: 1024,
  density: 600,
  outputdir: null,
  outputname: null,
  page: null
};

var Pdf2Img = function() {};

Pdf2Img.prototype.setOptions = function(opts) {
  options.type = opts.type || options.type;
  options.size = opts.size || options.size;
  options.density = opts.density || options.density;
  options.outputdir = opts.outputdir || options.outputdir;
  options.outputname = opts.outputname || options.outputname;
  options.page = opts.page || options.page;
};

Pdf2Img.prototype.convert = function(input, callbackreturn) {
  // Make sure it has correct extension
  if (path.extname(path.basename(input)) != '.pdf') {
    return callbackreturn({
      result: 'error',
      message: 'Unsupported file type.'
    });
  }

  // Check if input file exists
  if (!isFileExists(input)) {
    return callbackreturn({
      result: 'error',
      message: 'Input file not found.'
    });
  }

  var stdout = [];
  var output = path.basename(input, path.extname(path.basename(input)));

  // Set output dir
  if (options.outputdir) {
    options.outputdir = options.outputdir + path.sep;
  } else {
    options.outputdir = output + path.sep;
  }

  // Create output dir if it doesn't exists
  if (!isDirExists(options.outputdir)) {
    fs.mkdirSync(options.outputdir);
  }

  // Set output name
  if (options.outputname) {
    options.outputname = options.outputname;
  } else {
    options.outputname = output;
  }

  async.waterfall([
    // Get pages count
        function (callback) {
             gm(input).identify("%p ", function (err, value) {
                var pageCount = String(value).split(' ');

                if (!pageCount.length) {
                    callback({
                        result: 'error',
                        message: 'Invalid page number.'
                    }, null);
                } else {
                    // Convert selected page
                    if (options.page !== null) {
                        if (options.page <= pageCount.length) {
                            callback(null, [options.page]);
                        } else {
                            callback({
                                result: 'error',
                                message: 'Invalid page number.'
                            }, null);
                        }
                    } else  {
                        callback(null, pageCount);
                    }
                }

            })

        },

    // Convert pdf file
    function(pages, callback) {
      // Use eachSeries to make sure that conversion has done page by page
      async.eachSeries(pages, function(page, callbackmap) {
        var inputStream = fs.createReadStream(input);
        var outputFile = options.outputdir + options.outputname + '_' + page + '.' + options.type;

        convertPdf2Img(inputStream, outputFile, parseInt(page), function(error, result) {
          if (error) {
            return callbackmap(error);
          }

          stdout.push(result);
          return callbackmap(error, result);
        });
      }, function(e) {
        if (e) callback(e);

        return callback(null, {
          result: 'success',
          message: stdout
        });
      });
    }
  ], callbackreturn);
};

var convertPdf2Img = function(input, output, page, callback) {
  if (input.path) {
    var filepath = input.path;
  } else {
    return callback({
      result: 'error',
      message: 'Invalid input file path.'
    }, null);
  }

  var filename = filepath + '[' + (page - 1) + ']';

  gm(input, filename)
    .density(options.density, options.density)
    .resize(options.size)
    .quality(100)
    .write(output, function(err) {
      if (err) {
        return callback({
          result: 'error',
          message: 'Can not write output file.'
        }, null);
      }

      if (!(fs.statSync(output)['size'] / 1000)) {
        return callback({
          result: 'error',
          message: 'Zero sized output image detected.'
        }, null);
      }

      var results = {
        page: page,
        name: path.basename(output),
        size: fs.statSync(output)['size'] / 1000.0,
        path: output
      };

      return callback(null, results);
    });
};

// Check if directory is exists
var isDirExists = function(path) {
  try {
    return fs.statSync(path).isDirectory();
  } catch (e) {
    return false;
  }
}

// Check if file is exists
var isFileExists = function(path) {
  try {
    return fs.statSync(path).isFile();
  } catch (e) {
    return false;
  }
}

module.exports = new Pdf2Img;
<|endoftext|>


<commit_before>/**
 * Babel JavaScript Support
 *
 * Copyright (C) 2008 Edgewall Software
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://babel.edgewall.org/wiki/License.
 *
 * This software consists of voluntary contributions made by many
 * individuals. For the exact contribution history, see the revision
 * history and logs, available at http://babel.edgewall.org/log/.
 */

/**
 * A simple module that provides a gettext like translation interface.
 * The catalog passed to load() must be a object conforming to this
 * interface::
 *
 *    {
 *      messages:     an object of {msgid: translations} items where
 *                    translations is an array of messages or a single
 *                    string if the message is not pluralizable.
 *      plural_expr:  the plural expression for the language.
 *      locale:       the identifier for this locale.
 *      domain:       the name of the domain.
 *    }
 *
 * Missing elements in the object are ignored.
 *
 * Typical usage::
 *
 *    var translations = babel.Translations.load(...).install();
 */
var babel = new function() {

  var defaultPluralExpr = function(n) { return n == 1 ? 0 : 1; };
  var formatRegex = /%(?:(?:\(([^\)]+)\))?([disr])|%)/g;

  /**
   * A translations object implementing the gettext interface
   */
  var Translations = this.Translations = function(locale, domain) {
    this.messages = {};
    this.locale = locale || 'unknown';
    this.domain = domain || 'messages';
    this.pluralexpr = defaultPluralExpr;
  };

  /**
   * Create a new translations object from the catalog and return it.
   * See the babel-module comment for more details.
   */
  Translations.load = function(catalog) {
    var rv = new Translations();
    rv.load(catalog);
    return rv;
  };

  Translations.prototype = {
    /**
     * translate a single string
     *
     * If extra parameters are given, use them to fill the format
     * specified by the string.
     */
    gettext: function(string) {
      var translated = this.messages[string];
      if (typeof translated == 'undefined')
        return string;
      if (typeof translated != 'string')
        translated = translated[0];
      if (arguments.length > 1) {
        arguments[0] = translated;
        return babel.format.apply(this, arguments);
      }
      return translated;
    },

    /**
     * translate a pluralizable string
     *
     * If extra parameters are given, use them to fill the format
     * specified by the string.
     */
    ngettext: function(singular, plural, n) {
      var translated = this.messages[singular];
      if (typeof translated == 'undefined')
        translated = (n == 1) ? singular : plural;
      else
        translated = translated[this.pluralexpr(n)];
      if (arguments.length > 3) {
        var format_args = Array.prototype.slice.call(arguments, 3);
        format_args.unshift(translated);
        return babel.format.apply(this, format_args)
      }
      return translated;
    },

    /**
     * Install this translation document wide.  After this call, there are
     * three new methods on the window object: _, gettext and ngettext
     */
    install: function() {
      var self = this;
      window._ = window.gettext = function() {
        return self.gettext.apply(self, arguments);
      };
      window.ngettext = function(singular, plural, n) {
        return self.ngettext.apply(self, arguments);
      };
      return this;
    },

    /**
     * Works like Translations.load but updates the instance rather
     * then creating a new one.
     */
    load: function(catalog) {
      if (catalog.messages)
        this.update(catalog.messages)
      if (catalog.plural_expr)
        this.setPluralExpr(catalog.plural_expr);
      if (catalog.locale)
        this.locale = catalog.locale;
      if (catalog.domain)
        this.domain = catalog.domain;
      return this;
    },

    /**
     * Updates the translations with the object of messages.
     */
    update: function(mapping) {
      for (var key in mapping)
        if (mapping.hasOwnProperty(key))
          this.messages[key] = mapping[key];
      return this;
    },

    /**
     * Sets the plural expression
     */
    setPluralExpr: function(expr) {
      this.pluralexpr = new Function('n', 'return +(' + expr + ')');
      return this;
    }
  };

  /**
   * A python inspired string formatting function.  Supports named and
   * positional placeholders and "s", "d" and "i" as type characters
   * without any formatting specifications.
   *
   * Examples::
   *
   *    babel.format(_('Hello %s'), name)
   *    babel.format(_('Progress: %(percent)s%%'), {percent: 100})
   */
  this.format = function() {
    var arg, string = arguments[0], idx = 0;
    if (arguments.length == 1)
      return string;
    else if (arguments.length == 2 && typeof arguments[1] == 'object')
      arg = arguments[1];
    else {
      arg = [];
      for (var i = 1, n = arguments.length; i != n; ++i)
        arg[i - 1] = arguments[i];
    }
    return string.replace(formatRegex, function(all, name, type) {
      if (all == '%%') return '%';
      var value = arg[name || idx++];
      return (type == 'i' || type == 'd') ? +value : value;
    });
  }

};
<commit_msg>1.0dev: in babel.js gettext, also format strings not found in catalog.<commit_after>/**
 * Babel JavaScript Support
 *
 * Copyright (C) 2008 Edgewall Software
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://babel.edgewall.org/wiki/License.
 *
 * This software consists of voluntary contributions made by many
 * individuals. For the exact contribution history, see the revision
 * history and logs, available at http://babel.edgewall.org/log/.
 */

/**
 * A simple module that provides a gettext like translation interface.
 * The catalog passed to load() must be a object conforming to this
 * interface::
 *
 *    {
 *      messages:     an object of {msgid: translations} items where
 *                    translations is an array of messages or a single
 *                    string if the message is not pluralizable.
 *      plural_expr:  the plural expression for the language.
 *      locale:       the identifier for this locale.
 *      domain:       the name of the domain.
 *    }
 *
 * Missing elements in the object are ignored.
 *
 * Typical usage::
 *
 *    var translations = babel.Translations.load(...).install();
 */
var babel = new function() {

  var defaultPluralExpr = function(n) { return n == 1 ? 0 : 1; };
  var formatRegex = /%(?:(?:\(([^\)]+)\))?([disr])|%)/g;

  /**
   * A translations object implementing the gettext interface
   */
  var Translations = this.Translations = function(locale, domain) {
    this.messages = {};
    this.locale = locale || 'unknown';
    this.domain = domain || 'messages';
    this.pluralexpr = defaultPluralExpr;
  };

  /**
   * Create a new translations object from the catalog and return it.
   * See the babel-module comment for more details.
   */
  Translations.load = function(catalog) {
    var rv = new Translations();
    rv.load(catalog);
    return rv;
  };

  Translations.prototype = {
    /**
     * translate a single string
     *
     * If extra parameters are given, use them to fill the format
     * specified by the string.
     */
    gettext: function(string) {
      var translated = this.messages[string];
      if (typeof translated == 'undefined')
        translated = string;
      else if (typeof translated != 'string')
        translated = translated[0];
      if (arguments.length > 1) {
        arguments[0] = translated;
        return babel.format.apply(this, arguments);
      }
      return translated;
    },

    /**
     * translate a pluralizable string
     *
     * If extra parameters are given, use them to fill the format
     * specified by the string.
     */
    ngettext: function(singular, plural, n) {
      var translated = this.messages[singular];
      if (typeof translated == 'undefined')
        translated = (n == 1) ? singular : plural;
      else
        translated = translated[this.pluralexpr(n)];
      if (arguments.length > 3) {
        var format_args = Array.prototype.slice.call(arguments, 3);
        format_args.unshift(translated);
        return babel.format.apply(this, format_args)
      }
      return translated;
    },

    /**
     * Install this translation document wide.  After this call, there are
     * three new methods on the window object: _, gettext and ngettext
     */
    install: function() {
      var self = this;
      window._ = window.gettext = function() {
        return self.gettext.apply(self, arguments);
      };
      window.ngettext = function(singular, plural, n) {
        return self.ngettext.apply(self, arguments);
      };
      return this;
    },

    /**
     * Works like Translations.load but updates the instance rather
     * then creating a new one.
     */
    load: function(catalog) {
      if (catalog.messages)
        this.update(catalog.messages)
      if (catalog.plural_expr)
        this.setPluralExpr(catalog.plural_expr);
      if (catalog.locale)
        this.locale = catalog.locale;
      if (catalog.domain)
        this.domain = catalog.domain;
      return this;
    },

    /**
     * Updates the translations with the object of messages.
     */
    update: function(mapping) {
      for (var key in mapping)
        if (mapping.hasOwnProperty(key))
          this.messages[key] = mapping[key];
      return this;
    },

    /**
     * Sets the plural expression
     */
    setPluralExpr: function(expr) {
      this.pluralexpr = new Function('n', 'return +(' + expr + ')');
      return this;
    }
  };

  /**
   * A python inspired string formatting function.  Supports named and
   * positional placeholders and "s", "d" and "i" as type characters
   * without any formatting specifications.
   *
   * Examples::
   *
   *    babel.format(_('Hello %s'), name)
   *    babel.format(_('Progress: %(percent)s%%'), {percent: 100})
   */
  this.format = function() {
    var arg, string = arguments[0], idx = 0;
    if (arguments.length == 1)
      return string;
    else if (arguments.length == 2 && typeof arguments[1] == 'object')
      arg = arguments[1];
    else {
      arg = [];
      for (var i = 1, n = arguments.length; i != n; ++i)
        arg[i - 1] = arguments[i];
    }
    return string.replace(formatRegex, function(all, name, type) {
      if (all == '%%') return '%';
      var value = arg[name || idx++];
      return (type == 'i' || type == 'd') ? +value : value;
    });
  }

};
<|endoftext|>


<commit_before>/*
# Traffic Source Tracker - Google Analytics Last Non Direct Click Model
# Copyright (c) 2015, MarketLytics
#
# This project is free software, distributed under the MIT license.
# MarketLytics offers digital analytics consulting and integration services.
*/
(function (window, document)
{

	if(typeof JSON === 'undefined') {
		var fileref = document.createElement('script');
		fileref.setAttribute('type', 'text/javascript');
		fileref.setAttribute('src', '//cdnjs.cloudflare.com/ajax/libs/json2/20150503/json2.min.js');
		document.getElementsByTagName("head")[0].appendChild(fileref);
	}

	// set cookie name
	var cookieStrKey = 'traffic_src';

	//inject global function for cookie retrieval
	window.getTrafficSrcCookie = function()
	{
		var cookies = document.cookie.split(';');
		var cookieObj;
		for(var i = 0; i < cookies.length; i++) {
			if(cookies[i].indexOf(cookieStrKey) >= 0) {
				cookieObj = cookies[i];
				break;
			}
		}
		if(cookieObj)
		{
			cookieObj = cookieObj.substring(cookieObj.indexOf('=') + 1, cookieObj.length);
			return JSON.parse(cookieObj);
		}
		return null;
	};

	var utils = {
		getParameterByName: function(url, name)
		{
			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
			var results = regex.exec(url);
			return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
		},

		getKeywords: function(url)
		{
			if(url === '' || url === '(direct)') return '';

			var searchEngines = 'daum:q eniro:search_word naver:query pchome:q images.google:q google:q yahoo:p yahoo:q msn:q bing:q aol:query aol:q lycos:q lycos:query ask:q cnn:query virgilio:qs baidu:wd baidu:word alice:qs yandex:text najdi:q seznam:q rakuten:qt biglobe:q goo.ne:MT search.smt.docomo:MT onet:qt onet:q kvasir:q terra:query rambler:query conduit:q babylon:q search-results:q avg:q comcast:q incredimail:q startsiden:q go.mail.ru:q centrum.cz:q 360.cn:q sogou:query tut.by:query globo:q ukr:q so.com:q haosou.com:q auone:q'.split(' ');
			for(var i = 0; i < searchEngines.length; i++)
			{
				var val = searchEngines[i].split(':');
				var name = val[0];
				var queryParam = val[1];
				if(url.indexOf(name) >= 0){
					// set source of traffic to search engine
					cookieObj.ga_source = name;
					if(this.getParameterByName(url, queryParam) !== '') {
						return this.getParameterByName(url, queryParam);
					}
				}
			}

			var google = new RegExp('^https?:\/\/(www\.)?google(\.com?)?(\.[a-z]{2}t?)?\/?$', 'i');
			var yahoo = new RegExp('^https?:\/\/(r\.)?search\.yahoo\.com\/?[^?]*$', 'i');
			var bing = new RegExp('^https?:\/\/(www\.)?bing\.com\/?$', 'i');
			if(google.test(url) || yahoo.test(url) || bing.test(url)) {
				return '(not provided)';
			}

			return '';
		},

		getMedium: function(ccokieObj)
		{
			if(cookieObj.ga_medium !== '') return cookieObj.ga_medium;

			if(cookieObj.ga_gclid !== '') return 'cpc';

			if(cookieObj.ga_source === '') return '';

			if(cookieObj.ga_source === '(direct)') return '(none)';

			if(cookieObj.ga_keyword !== '') return 'organic';

			return 'referral';
		},

		getDateAfterYears: function(years)
		{
			return new Date(new Date().getTime() + (years * 365 * 24 * 60 * 60 * 1000));
		},

		getHostname: function(url)
		{
			var re = new RegExp('^(https:\/\/|http:\/\/)?([^\/?:#]+)');
			var match = re.exec(url)[2];
			if(match !== null) {
				return match;
			}
			return '';
		},

		waitLoad: function(condition, callback) {
			var timeout = 100;
			var poll = function() {
				setTimeout(function() {
					timeout--;
					if(condition()) {
						callback();
					} else if (timeout > 0) {
						poll();
					} else {
						console.error('timed-out!!');
					}
				}, 100);
			};
			poll();
		}
    };

    // query params keys to look for to get utm data
	var parameters = [{
		key: 'utm_source',
		label: 'ga_source',
		required:  true
	}, {
		key: 'utm_medium',
		label: 'ga_medium',
		required: true
	}, {
		key: 'utm_campaign',
		label: 'ga_campaign',
		required: true
	}, {
		key: 'utm_content',
		label: 'ga_content',
		required: false
	}, {
		key: 'utm_term',
		label: 'ga_keyword',
		required: false
	}];

	var cookieObj = {};

	var setCookie = function()
	{
		cookieObj.ga_gclid = utils.getParameterByName(document.location.href, 'gclid');

		var ignoreUtmParameters = false;
		for(var i = 0; i < parameters.length; i++) {
			var value = utils.getParameterByName(document.location.href, parameters[i].key);
			if(parameters[i].required && value === '') {
				ignoreUtmParameters = true;
				for(var j = 0; j < parameters.length; j++) {
					cookieObj[parameters[j]['label']] = '';
				}
				break;
			}
			cookieObj[parameters[i]['label']] = value;
		}

		if (cookieObj.ga_gclid !== '' && cookieObj.ga_source === '')
		{
			cookieObj.ga_source = 'google';
		}
		else if(ignoreUtmParameters)
		{
			if(document.referrer.indexOf(document.location.host) >= 0) return;
			if(window.getTrafficSrcCookie() !== null && document.referrer === '') return;
			cookieObj.ga_source = document.referrer !== '' ? document.referrer : '(direct)';
		}

		cookieObj.ga_keyword = cookieObj.ga_keyword === '' ? utils.getKeywords(cookieObj.ga_source) : cookieObj.ga_keyword;
		cookieObj.ga_medium = utils.getMedium(cookieObj);
		cookieObj.ga_landing_page = document.location.href;
		cookieObj.ga_source = utils.getHostname(cookieObj.ga_source);
		cookieObj.ga_client_id = ga.getAll()[0].get('clientId');

		if(cookieObj.ga_source !== '') {
			var cookieStr = JSON.stringify(cookieObj);
			document.cookie = cookieStrKey + '=; expires=' + new Date(-1);
			document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1) + '; path=/';
		}

	};

	utils.waitLoad(function() {
		return typeof JSON !== 'undefined';
	}, function() {
		utils.waitLoad(function() {
			return typeof ga.getAll !== 'undefined';
		}, setCookie);
	});

})(window, document)
<commit_msg>Update trafficSourceTracker.js<commit_after>/*
# Traffic Source Tracker - Google Analytics Last Non Direct Click Model
# Copyright (c) 2015, MarketLytics
#
# This project is free software, distributed under the MIT license.
# MarketLytics offers digital analytics consulting and integration services.
*/
(function (window, document)
{
	//including javascript in web page when JSON is undifined(first time), creating json source attribute, appending in head tag
	if(typeof JSON === 'undefined') {
		var fileref = document.createElement('script');
		fileref.setAttribute('type', 'text/javascript');
		fileref.setAttribute('src', '//cdnjs.cloudflare.com/ajax/libs/json2/20150503/json2.min.js');
		document.getElementsByTagName("head")[0].appendChild(fileref);
	}

	// since we need to find traffic source value from cookie, we search for it, and get its value if >=0
	var cookieStrKey = 'traffic_src';

	//inject global function for cookie retrieval
	window.getTrafficSrcCookie = function()
	{	//split cookie into string array
		var cookies = document.cookie.split(';');
		var cookieObj;
		for(var i = 0; i < cookies.length; i++) {
			//indexOf gets starting index of traffic_src
			if(cookies[i].indexOf(cookieStrKey) >= 0) {
				//stoing
				cookieObj = cookies[i];
				break;
			}
		}
		//removing '=' from cookieObj and parsing value to JSON when its value exist
		if(cookieObj)
		{
			cookieObj = cookieObj.substring(cookieObj.indexOf('=') + 1, cookieObj.length);
			return JSON.parse(cookieObj);
		}
		//return null if no value was found in cookieObj
		return null;
	};

	var utils = {
		//function compares url value from modified name value
		getParameterByName: function(url, name)
		{
			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
			//exec function takes modified(using replace and RegExp) name value and search it in url
			var results = regex.exec(url);
			//if null return empty string, or else return decoded value of name along with value replacement
			return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
		},

		getKeywords: function(url)
		{	//return empty sting if url is empty or direct
			if(url === '' || url === '(direct)') return '';

			var searchEngines = 'daum:q eniro:search_word naver:query pchome:q images.google:q google:q yahoo:p yahoo:q msn:q bing:q aol:query aol:q lycos:q lycos:query ask:q cnn:query virgilio:qs baidu:wd baidu:word alice:qs yandex:text najdi:q seznam:q rakuten:qt biglobe:q goo.ne:MT search.smt.docomo:MT onet:qt onet:q kvasir:q terra:query rambler:query conduit:q babylon:q search-results:q avg:q comcast:q incredimail:q startsiden:q go.mail.ru:q centrum.cz:q 360.cn:q sogou:query tut.by:query globo:q ukr:q so.com:q haosou.com:q auone:q'.split(' ');
			for(var i = 0; i < searchEngines.length; i++)
			{
				var val = searchEngines[i].split(':');
				var name = val[0];
				var queryParam = val[1];
				if(url.indexOf(name) >= 0){
					// set source of traffic to search engine
					cookieObj.ga_source = name;
					if(this.getParameterByName(url, queryParam) !== '') {
						//return value of queryParamter, extracted keyowrd
						return this.getParameterByName(url, queryParam);
					}
				}
			}
		//if url belongs to google, bing or yahoo return not provided
			var google = new RegExp('^https?:\/\/(www\.)?google(\.com?)?(\.[a-z]{2}t?)?\/?$', 'i');
			var yahoo = new RegExp('^https?:\/\/(r\.)?search\.yahoo\.com\/?[^?]*$', 'i');
			var bing = new RegExp('^https?:\/\/(www\.)?bing\.com\/?$', 'i');
			if(google.test(url) || yahoo.test(url) || bing.test(url)) {
				return '(not provided)';
			}

			return '';
		},
	//getting source medium, return anyone of the following cookieObj.ga_medium, 'cpc','',(none),'organic','referral'
		getMedium: function(ccokieObj)
		{
			if(cookieObj.ga_medium !== '') return cookieObj.ga_medium;

			if(cookieObj.ga_gclid !== '') return 'cpc';

			if(cookieObj.ga_source === '') return '';

			if(cookieObj.ga_source === '(direct)') return '(none)';

			if(cookieObj.ga_keyword !== '') return 'organic';

			return 'referral';
		},
	//getting current date
		getDateAfterYears: function(years)
		{
			return new Date(new Date().getTime() + (years * 365 * 24 * 60 * 60 * 1000));
		},
	//getting hostname
		getHostname: function(url)
		{
			var re = new RegExp('^(https:\/\/|http:\/\/)?([^\/?:#]+)');
			var match = re.exec(url)[2];
			if(match !== null) {
				return match;
			}
			return '';
		},
	//setting 100millisecond wait, set wait between condtion and callback function
		waitLoad: function(condition, callback) {
			var timeout = 100;
			var poll = function() {
				setTimeout(function() {
					timeout--;
					if(condition()) {
						callback();
					} else if (timeout > 0) {
						poll();
					} else {
						console.error('timed-out!!');
					}
				}, 100);
			};
			poll();
		}
    };

    // query params keys to look for to get utm data
	var parameters = [{
		key: 'utm_source',
		label: 'ga_source',
		required:  true
	}, {
		key: 'utm_medium',
		label: 'ga_medium',
		required: true
	}, {
		key: 'utm_campaign',
		label: 'ga_campaign',
		required: true
	}, {
		key: 'utm_content',
		label: 'ga_content',
		required: false
	}, {
		key: 'utm_term',
		label: 'ga_keyword',
		required: false
	}];

	var cookieObj = {};
	 //gclid = checks for value passed between google and adwords
	var setCookie = function()
	{//search for gclid in entire url
		cookieObj.ga_gclid = utils.getParameterByName(document.location.href, 'gclid');

		var ignoreUtmParameters = false;
		for(var i = 0; i < parameters.length; i++) {
			var value = utils.getParameterByName(document.location.href, parameters[i].key);
			if(parameters[i].required && value === '') {
				ignoreUtmParameters = true;
				for(var j = 0; j < parameters.length; j++) {
					cookieObj[parameters[j]['label']] = '';
				}
				break;
			}
			cookieObj[parameters[i]['label']] = value;
		}
		// if gclif is empty and soruce is empty set source to google
		if (cookieObj.ga_gclid !== '' && cookieObj.ga_source === '')
		{
			cookieObj.ga_source = 'google';
		}
		else if(ignoreUtmParameters)
		{ //check for refferrer url and url of current page, if both are same return direct as source
			if(document.referrer.indexOf(document.location.host) >= 0) return;
			if(window.getTrafficSrcCookie() !== null && document.referrer === '') return;
			cookieObj.ga_source = document.referrer !== '' ? document.referrer : '(direct)';
		}
		//if there is no keyword value reutrn source, else return keyword value
		cookieObj.ga_keyword = cookieObj.ga_keyword === '' ? utils.getKeywords(cookieObj.ga_source) : cookieObj.ga_keyword;
		cookieObj.ga_medium = utils.getMedium(cookieObj);
		//get landing page as href value of given document
		cookieObj.ga_landing_page = document.location.href;
		cookieObj.ga_source = utils.getHostname(cookieObj.ga_source);
		cookieObj.ga_client_id = ga.getAll()[0].get('clientId');

		//coverting cookieObj o JSON String
		if(cookieObj.ga_source !== '') {
			//coverting Javascript value under cookieObj to JSON String
			var cookieStr = JSON.stringify(cookieObj);
			document.cookie = cookieStrKey + '=; expires=' + new Date(-1);
			document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1) + '; path=/';
		}

	};

	utils.waitLoad(function() {
		//works if JSON is not undedfined
		return typeof JSON !== 'undefined';
	}, function() {
		//works when Analytics tracker(ga) exists on site
		utils.waitLoad(function() {
			return typeof ga.getAll !== 'undefined';
		}, setCookie);
	});

})(window, document)
<|endoftext|>


<commit_before>// Mathieu Jacomy @ Sciences Po Médialab & WebAtlas
// (requires sigma.js to be loaded)
sigma.publicPrototype.parseGexf = function(gexfPath) {
  // Load XML file:
  var gexfhttp, gexf;
  var sigmaInstance = this;
  gexfhttp = window.XMLHttpRequest ?
    new XMLHttpRequest() :
    new ActiveXObject('Microsoft.XMLHTTP');

  gexfhttp.overrideMimeType('text/xml');
  gexfhttp.open('GET', gexfPath, false);
  gexfhttp.send();
  gexf = gexfhttp.responseXML;

  var viz='http://www.gexf.net/1.2draft/viz'; // Vis namespace
  var i, j, k;

  // Parse Attributes
  // This is confusing, so I'll comment heavily
  var nodesAttributes = [];   // The list of attributes of the nodes of the graph that we build in json
  var edgesAttributes = [];   // The list of attributes of the edges of the graph that we build in json
  var attributesNodes = gexf.getElementsByTagName('attributes');  // In the gexf (that is an xml), the list of xml nodes 'attributes' (note the plural 's')

  for(i = 0; i<attributesNodes.length; i++){
    var attributesNode = attributesNodes[i];  // attributesNode is each xml node 'attributes' (plural)
    if(attributesNode.getAttribute('class') == 'node'){
      var attributeNodes = attributesNode.getElementsByTagName('attribute');  // The list of xml nodes 'attribute' (no 's')
      for(j = 0; j<attributeNodes.length; j++){
        var attributeNode = attributeNodes[j];  // Each xml node 'attribute'

        var id = attributeNode.getAttribute('id'),
          title = attributeNode.getAttribute('title'),
          type = attributeNode.getAttribute('type');

        var attribute = {id:id, title:title, type:type};
        nodesAttributes.push(attribute);

      }
    } else if(attributesNode.getAttribute('class') == 'edge'){
      var attributeNodes = attributesNode.getElementsByTagName('attribute');  // The list of xml nodes 'attribute' (no 's')
      for(j = 0; j<attributeNodes.length; j++){
        var attributeNode = attributeNodes[j];  // Each xml node 'attribute'

        var id = attributeNode.getAttribute('id'),
          title = attributeNode.getAttribute('title'),
          type = attributeNode.getAttribute('type');

        var attribute = {id:id, title:title, type:type};
        edgesAttributes.push(attribute);

      }
    }
  }

  var nodes = []; // The nodes of the graph
  var nodesNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural)

  for(i=0; i<nodesNodes.length; i++){
    var nodesNode = nodesNodes[i];  // Each xml node 'nodes' (plural)
    var nodeNodes = nodesNode.getElementsByTagName('node'); // The list of xml nodes 'node' (no 's')

    for(j=0; j<nodeNodes.length; j++){
      var nodeNode = nodeNodes[j];  // Each xml node 'node' (no 's')

      window.NODE = nodeNode;

      var id = nodeNode.getAttribute('id');
      var label = nodeNode.getAttribute('label') || id;

      //viz
      var size = 1;
      var x = 100 - 200*Math.random();
      var y = 100 - 200*Math.random();
      var color;

      var poorBrowserXmlNsSupport = (nodeNode.getElementsByTagNameNS == null);

      var sizeNodes = nodeNode.getElementsByTagName('size');
      sizeNodes = sizeNodes.length || poorBrowserXmlNsSupport ?
                  sizeNodes :
                  nodeNode.getElementsByTagNameNS('*','size');
      if(sizeNodes.length>0){
        sizeNode = sizeNodes[0];
        size = parseFloat(sizeNode.getAttribute('value'));
      }

      var positionNodes = nodeNode.getElementsByTagName('position');
      positionNodes = positionNodes.length || poorBrowserXmlNsSupport ?
                      positionNodes :
                      nodeNode.getElementsByTagNameNS('*','position');
      if(positionNodes.length>0){
        var positionNode = positionNodes[0];
        x = parseFloat(positionNode.getAttribute('x'));
        y = parseFloat(positionNode.getAttribute('y'));
      }

      var colorNodes = nodeNode.getElementsByTagName('color');
      colorNodes = colorNodes.length || poorBrowserXmlNsSupport ?
                   colorNodes :
                   nodeNode.getElementsByTagNameNS('*','color');
      if(colorNodes.length>0){
        colorNode = colorNodes[0];
        color = '#'+sigma.tools.rgbToHex(parseFloat(colorNode.getAttribute('r')),
                                         parseFloat(colorNode.getAttribute('g')),
                                         parseFloat(colorNode.getAttribute('b')));
      }

      // Create Node
      var node = {label:label, size:size, x:x, y:y, attributes:[], color:color};  // The graph node

      // Attribute values
      var attvalueNodes = nodeNode.getElementsByTagName('attvalue');
      for(k=0; k<attvalueNodes.length; k++){
        var attvalueNode = attvalueNodes[k];
        var attr = attvalueNode.getAttribute('for');
        var val = attvalueNode.getAttribute('value');
        node.attributes.push({attr:attr, val:val});
      }

      sigmaInstance.addNode(id,node);
    }
  }

  var edges = [];
  var edgesNodes = gexf.getElementsByTagName('edges');
  for(i=0; i<edgesNodes.length; i++){
    var edgesNode = edgesNodes[i];
    var edgeNodes = edgesNode.getElementsByTagName('edge');
    for(j=0; j<edgeNodes.length; j++){
      var edgeNode = edgeNodes[j];
      var id = edgeNode.getAttribute('id');
      var source = edgeNode.getAttribute('source');
      var target = edgeNode.getAttribute('target');
      var label = edgeNode.getAttribute('label');
      var edge = {
        id:         id,
        sourceID:   source,
        targetID:   target,
        label:      label,
        attributes: []
      };

      var weight = edgeNode.getAttribute('weight');
      if(weight!=undefined){
        edge['weight'] = weight;
        edge['size'] = weight;
      }

      var attvalueNodes = edgeNode.getElementsByTagName('attvalue');
      for(k=0; k<attvalueNodes.length; k++){
        var attvalueNode = attvalueNodes[k];
        var attr = attvalueNode.getAttribute('for');
        var val = attvalueNode.getAttribute('value');
        edge.attributes.push({attr:attr, val:val});
      }

      sigmaInstance.addEdge(id,source,target,edge);
    }
  }
};
<commit_msg>IE doesn't support overrideMimeType<commit_after>// Mathieu Jacomy @ Sciences Po Médialab & WebAtlas
// (requires sigma.js to be loaded)
sigma.publicPrototype.parseGexf = function(gexfPath) {
  // Load XML file:
  var gexfhttp, gexf;
  var sigmaInstance = this;
  gexfhttp = window.XMLHttpRequest ?
    new XMLHttpRequest() :
    new ActiveXObject('Microsoft.XMLHTTP');

if (gexfhttp.overrideMimeType) {
    gexfhttp.overrideMimeType('text/xml');
}

  gexfhttp.open('GET', gexfPath, false);
  gexfhttp.send();
  gexf = gexfhttp.responseXML;

  var viz='http://www.gexf.net/1.2draft/viz'; // Vis namespace
  var i, j, k;

  // Parse Attributes
  // This is confusing, so I'll comment heavily
  var nodesAttributes = [];   // The list of attributes of the nodes of the graph that we build in json
  var edgesAttributes = [];   // The list of attributes of the edges of the graph that we build in json
  var attributesNodes = gexf.getElementsByTagName('attributes');  // In the gexf (that is an xml), the list of xml nodes 'attributes' (note the plural 's')

  for(i = 0; i<attributesNodes.length; i++){
    var attributesNode = attributesNodes[i];  // attributesNode is each xml node 'attributes' (plural)
    if(attributesNode.getAttribute('class') == 'node'){
      var attributeNodes = attributesNode.getElementsByTagName('attribute');  // The list of xml nodes 'attribute' (no 's')
      for(j = 0; j<attributeNodes.length; j++){
        var attributeNode = attributeNodes[j];  // Each xml node 'attribute'

        var id = attributeNode.getAttribute('id'),
          title = attributeNode.getAttribute('title'),
          type = attributeNode.getAttribute('type');

        var attribute = {id:id, title:title, type:type};
        nodesAttributes.push(attribute);

      }
    } else if(attributesNode.getAttribute('class') == 'edge'){
      var attributeNodes = attributesNode.getElementsByTagName('attribute');  // The list of xml nodes 'attribute' (no 's')
      for(j = 0; j<attributeNodes.length; j++){
        var attributeNode = attributeNodes[j];  // Each xml node 'attribute'

        var id = attributeNode.getAttribute('id'),
          title = attributeNode.getAttribute('title'),
          type = attributeNode.getAttribute('type');

        var attribute = {id:id, title:title, type:type};
        edgesAttributes.push(attribute);

      }
    }
  }

  var nodes = []; // The nodes of the graph
  var nodesNodes = gexf.getElementsByTagName('nodes') // The list of xml nodes 'nodes' (plural)

  for(i=0; i<nodesNodes.length; i++){
    var nodesNode = nodesNodes[i];  // Each xml node 'nodes' (plural)
    var nodeNodes = nodesNode.getElementsByTagName('node'); // The list of xml nodes 'node' (no 's')

    for(j=0; j<nodeNodes.length; j++){
      var nodeNode = nodeNodes[j];  // Each xml node 'node' (no 's')

      window.NODE = nodeNode;

      var id = nodeNode.getAttribute('id');
      var label = nodeNode.getAttribute('label') || id;

      //viz
      var size = 1;
      var x = 100 - 200*Math.random();
      var y = 100 - 200*Math.random();
      var color;

      var poorBrowserXmlNsSupport = (nodeNode.getElementsByTagNameNS == null);

      var sizeNodes = nodeNode.getElementsByTagName('size');
      sizeNodes = sizeNodes.length || poorBrowserXmlNsSupport ?
                  sizeNodes :
                  nodeNode.getElementsByTagNameNS('*','size');
      if(sizeNodes.length>0){
        sizeNode = sizeNodes[0];
        size = parseFloat(sizeNode.getAttribute('value'));
      }

      var positionNodes = nodeNode.getElementsByTagName('position');
      positionNodes = positionNodes.length || poorBrowserXmlNsSupport ?
                      positionNodes :
                      nodeNode.getElementsByTagNameNS('*','position');
      if(positionNodes.length>0){
        var positionNode = positionNodes[0];
        x = parseFloat(positionNode.getAttribute('x'));
        y = parseFloat(positionNode.getAttribute('y'));
      }

      var colorNodes = nodeNode.getElementsByTagName('color');
      colorNodes = colorNodes.length || poorBrowserXmlNsSupport ?
                   colorNodes :
                   nodeNode.getElementsByTagNameNS('*','color');
      if(colorNodes.length>0){
        colorNode = colorNodes[0];
        color = '#'+sigma.tools.rgbToHex(parseFloat(colorNode.getAttribute('r')),
                                         parseFloat(colorNode.getAttribute('g')),
                                         parseFloat(colorNode.getAttribute('b')));
      }

      // Create Node
      var node = {label:label, size:size, x:x, y:y, attributes:[], color:color};  // The graph node

      // Attribute values
      var attvalueNodes = nodeNode.getElementsByTagName('attvalue');
      for(k=0; k<attvalueNodes.length; k++){
        var attvalueNode = attvalueNodes[k];
        var attr = attvalueNode.getAttribute('for');
        var val = attvalueNode.getAttribute('value');
        node.attributes.push({attr:attr, val:val});
      }

      sigmaInstance.addNode(id,node);
    }
  }

  var edges = [];
  var edgesNodes = gexf.getElementsByTagName('edges');
  for(i=0; i<edgesNodes.length; i++){
    var edgesNode = edgesNodes[i];
    var edgeNodes = edgesNode.getElementsByTagName('edge');
    for(j=0; j<edgeNodes.length; j++){
      var edgeNode = edgeNodes[j];
      var id = edgeNode.getAttribute('id');
      var source = edgeNode.getAttribute('source');
      var target = edgeNode.getAttribute('target');
      var label = edgeNode.getAttribute('label');
      var edge = {
        id:         id,
        sourceID:   source,
        targetID:   target,
        label:      label,
        attributes: []
      };

      var weight = edgeNode.getAttribute('weight');
      if(weight!=undefined){
        edge['weight'] = weight;
        edge['size'] = weight;
      }

      var attvalueNodes = edgeNode.getElementsByTagName('attvalue');
      for(k=0; k<attvalueNodes.length; k++){
        var attvalueNode = attvalueNodes[k];
        var attr = attvalueNode.getAttribute('for');
        var val = attvalueNode.getAttribute('value');
        edge.attributes.push({attr:attr, val:val});
      }

      sigmaInstance.addEdge(id,source,target,edge);
    }
  }
};
<|endoftext|>


<commit_before>// ==UserScript==
// @id             tidy-links@boombuler
// @name           IITC plugin: Tidy Links
// @category       Draw
// @version        0.5.0.@@DATETIMEVERSION@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Calculate how to link the portals to create a reasonably tidy set of links/fields. Enable from the layer chooser. (former `Max Links`)
@@METAINFO@@
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
var tidyLinks = {};
window.plugin.tidyLinks = tidyLinks;

tidyLinks.MAX_PORTALS_TO_LINK = 200; // N.B.: this limit is not about performance

// zoom level used for projecting points between latLng and pixel coordinates. may affect precision of triangulation
tidyLinks.PROJECT_ZOOM = 16;

tidyLinks.STROKE_STYLE = { // https://leafletjs.com/reference-1.4.0.html#polyline-stroke
  color: 'red',
  opacity: 1,
  weight: 1.5,
  dashArray: '6,4',
  interactive: false
};

tidyLinks.errorMarkerIconOptions = { // https://leafletjs.com/reference-1.4.0.html#divicon-html
  className: 'tidy-links-error',
  iconSize: [300,30],
  html: 'Tidy Links: too many portals!'
};

var map, errorMarker;

function updateLayer () {
  var locations = [];
  var bounds = map.getBounds();
  $.each(window.portals, function (guid, portal) {
    var ll = portal.getLatLng();
    if (bounds.contains(ll)) {
      locations.push(ll);
      return locations.length <= tidyLinks.MAX_PORTALS_TO_LINK; // $.each break
    }
  });

  if (locations.length > tidyLinks.MAX_PORTALS_TO_LINK) {
    errorMarker.setLatLng(map.getCenter()).addTo(tidyLinks.layer);
    return;
  }

  var triangles = tidyLinks.Delaunay.triangulate(locations.map(function (latlng) {
    var point = map.project(latlng, tidyLinks.PROJECT_ZOOM);
    return [point.x,point.y];
  }));

  tidyLinks.layer.clearLayers();

  var drawnLinks = {};

  // draw a link, but only if it hasn't already been drawn
  function drawLink (a,b) {
    // order the points, so a pair of coordinates in any order is handled in one direction only
    if (a>b) { b = [a, a = b][0]; } // swap

    if (!(a in drawnLinks)) { // no lines from a to anywhere yet
      drawnLinks[a] = {};
    }

    if (!(b in drawnLinks[a])) { // no line from a to b yet
      drawnLinks[a][b] = true;
      L.polyline([locations[a], locations[b]], tidyLinks.STROKE_STYLE).addTo(tidyLinks.layer);
    }
  }
  for (var i = 0; i<triangles.length;) {
    var a = triangles[i++],
        b = triangles[i++],
        c = triangles[i++];
    drawLink(a,b);
    drawLink(b,c);
    drawLink(c,a);
  }
}

function setup () {
  tidyLinks.Delaunay = loadDelaunay();

  map = window.map;
  var icon = L.divIcon(tidyLinks.errorMarkerIconOptions);
  errorMarker = L.marker([0,0], { icon: icon, interactive: false });
  tidyLinks.layer = L.layerGroup([])
    .on('add', function () {
      updateLayer();
      window.addHook('mapDataRefreshEnd', updateLayer);
    })
    .on('remove', function () {
      window.removeHook('mapDataRefreshEnd', updateLayer);
    });

  window.addLayerGroup('Tidy Links', tidyLinks.layer, false);

  $('<style>').html('\
    .tidy-links-error {\
      color: #F88;\
      font-size: 20px;\
      font-weight: bold;\
      text-align: center;\
      text-shadow: -1px -1px #000, 1px -1px #000, -1px 1px #000, 1px 1px #000;\
      background-color: rgba(0,0,0,0.6);\
      border-radius: 5px;\
    }\
  ').appendTo('head');
}

function loadDelaunay () {
  try {
    // https://github.com/ironwallaby/delaunay
    @@INCLUDERAW:external/delaunay.js@@

    return Delaunay;
  } catch (e) {
    console.error('delaunay.js loading failed');
    throw e;
  }
}

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<commit_msg>tidy-links: use Tooltip instead of DivIcon<commit_after>// ==UserScript==
// @id             tidy-links@boombuler
// @name           IITC plugin: Tidy Links
// @category       Draw
// @version        0.5.0.@@DATETIMEVERSION@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Calculate how to link the portals to create a reasonably tidy set of links/fields. Enable from the layer chooser. (former `Max Links`)
@@METAINFO@@
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
var tidyLinks = {};
window.plugin.tidyLinks = tidyLinks;

tidyLinks.MAX_PORTALS_TO_LINK = 200; // N.B.: this limit is not about performance

// zoom level used for projecting points between latLng and pixel coordinates. may affect precision of triangulation
tidyLinks.PROJECT_ZOOM = 16;

tidyLinks.STROKE_STYLE = { // https://leafletjs.com/reference-1.4.0.html#polyline-stroke
  color: 'red',
  opacity: 1,
  weight: 1.5,
  dashArray: '6,4',
  interactive: false
};

var map;

tidyLinks.draw = function () {
  var locations = [];
  var bounds = map.getBounds();
  $.each(window.portals, function (guid, portal) {
    var ll = portal.getLatLng();
    if (bounds.contains(ll)) {
      locations.push(ll);
      return locations.length <= tidyLinks.MAX_PORTALS_TO_LINK; // $.each break
    }
  });

  if (locations.length > tidyLinks.MAX_PORTALS_TO_LINK) { return; }

  var triangles = tidyLinks.Delaunay.triangulate(locations.map(function (latlng) {
    var point = map.project(latlng, tidyLinks.PROJECT_ZOOM);
    return [point.x,point.y];
  }));

  tidyLinks.layer.clearLayers();

  var drawnLinks = {};

  // draw a link, but only if it hasn't already been drawn
  function drawLink (a,b) {
    // order the points, so a pair of coordinates in any order is handled in one direction only
    if (a>b) { b = [a, a = b][0]; } // swap

    if (!(a in drawnLinks)) { // no lines from a to anywhere yet
      drawnLinks[a] = {};
    }

    if (!(b in drawnLinks[a])) { // no line from a to b yet
      drawnLinks[a][b] = true;
      L.polyline([locations[a], locations[b]], tidyLinks.STROKE_STYLE).addTo(tidyLinks.layer);
    }
  }
  for (var i = 0; i<triangles.length;) {
    var a = triangles[i++],
        b = triangles[i++],
        c = triangles[i++];
    drawLink(a,b);
    drawLink(b,c);
    drawLink(c,a);
  }
  return true;
};

tidyLinks.setOverflow = function (isOveflowed) {
  tidyLinks.layer[isOveflowed ? 'openTooltip' : 'closeTooltip']();
};

tidyLinks.update = function () {
  tidyLinks.setOverflow(!tidyLinks.draw());
};

function setup () {
  tidyLinks.Delaunay = loadDelaunay();

  map = window.map;
  tidyLinks.layer = L.layerGroup([])
    .on('add', function () {
      tidyLinks.update();
      window.addHook('mapDataRefreshEnd', tidyLinks.update);
    })
    .on('remove', function () {
      window.removeHook('mapDataRefreshEnd', tidyLinks.update);
    })
    .bindTooltip('Tidy Links: too many portals!', {
      className: 'tidy-links-error',
      direction: 'center'
    });
  tidyLinks.layer.getCenter = function () { return map.getCenter(); }; // for tooltip position

  window.addLayerGroup('Tidy Links', tidyLinks.layer, false);

  $('<style>').html('\
    .tidy-links-error {\
      color: #F88;\
      font-size: 20px;\
      font-weight: bold;\
      text-align: center;\
      text-shadow: -1px -1px #000, 1px -1px #000, -1px 1px #000, 1px 1px #000;\
      background-color: rgba(0,0,0,0.6);\
      width: 300px;\
      border: none;\
    }\
  ').appendTo('head');
}

function loadDelaunay () {
  try {
    // https://github.com/ironwallaby/delaunay
    @@INCLUDERAW:external/delaunay.js@@

    return Delaunay;
  } catch (e) {
    console.error('delaunay.js loading failed');
    throw e;
  }
}

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<|endoftext|>


<commit_before>var interpret=i=>{
	var stack=[],//stack
		//I/O functions
		_=i=>[i=prompt`Input:`,stack.push(i)][0]//input
		$=i=>alert(i!=[]._?i:stack),//output

		//stack functions
		p=i=>stack.push(i),//push to stack
		g=i=>i!=[]._?stack[i<0?stack.length+i:i]:stack[stack.length-1],//get item from stack
		s=i=>stack.splice(i!=[]._?i:stack.length-1),//splice item from stack
		c=i=>stack=[],//clear stack

		//extra math stuff
		P=(i='g()¢2',j)=>[i=i.split`¢`,j=Math.pow(i[0]!=[]._?eval(i[0]):g(),i[1]!=[]._?eval(i[1]):2),p(j)][1],//number^exponent
		R=(i='0¢1',j,x,y)=>[i=i.split`¢`,j=0|Math.random()*(i[1]-i[0]+1)+i[0],p(j)][1],//random

		//other functions and builtins
		i=i=>(i=i.split`¢`,eval(`if(${i[0]}){${i[1]}}else{${i[2]}}`)),//if/else conditional statements
		l=i=>(i=i.split`¢`,eval(`for(${i[0]}){${i[1]}}`)),//loop
		S=i=>[i=i!=[]._?document.getElementById('c').value[i]:document.getElementById('c').value,stack.push(i)][0],//get source code (chars)
		e=eval,
		m=Math,
		r=(i,j)=>(p(j=[...i].reverse().join``),j),

		//syntax from esmin to es6
		i=document.getElementById('c').value
			.replace(/([^\\])@/g,'$1()')
			.replace(/~>/g,'=()=>')
			.replace(/([pgs$])(-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'$1($2)')
			.replace(/([_$a-zA-Z]*)“(.*?)”?$/g,'$1(`$2`)')
			.replace(/([_$a-zA-Z]*)‘(.*?)’?$/g,'$1($2)')
			.replace(/([^\\])∞/g,'$1Infinity')
		  .replace(/…/g,'...')
	if(!i.match(/\$[^{]/g))i+=';$()';
	e(i);
}<commit_msg>add length function<commit_after>var interpret=i=>{
	var stack=[],//stack
		//I/O functions
		_=i=>[i=prompt`Input:`,stack.push(i)][0]//input
		$=i=>alert(i!=[]._?i:stack),//output

		//stack functions
		p=i=>stack.push(i),//push to stack
		g=i=>i!=[]._?stack[i<0?stack.length+i:i]:stack[stack.length-1],//get item from stack
		s=i=>stack.splice(i!=[]._?i:stack.length-1),//splice item from stack
		c=i=>stack=[],//clear stack

		//extra math stuff
		P=(i='g()¢2',j)=>[i=i.split`¢`,j=Math.pow(i[0]!=[]._?eval(i[0]):g(),i[1]!=[]._?eval(i[1]):2),p(j)][1],//number^exponent
		R=(i='0¢1',j,x,y)=>[i=i.split`¢`,j=0|Math.random()*(i[1]-i[0]+1)+i[0],p(j)][1],//random

		//other functions and builtins
		i=i=>(i=i.split`¢`,eval(`if(${i[0]}){${i[1]}}else{${i[2]}}`)),//if/else conditional statements
		l=i=>(i=i.split`¢`,eval(`for(${i[0]}){${i[1]}}`)),//loop
		S=i=>[i=i!=[]._?document.getElementById('c').value[i]:document.getElementById('c').value,stack.push(i)][0],//get source code chars
		e=eval,
		m=Math,
		r=(i,j)=>(p(j=[...i].reverse().join``),j),
		L=i=>i.length,//get length

		//syntax from esmin to es6
		i=document.getElementById('c').value
			.replace(/([^\\])@/g,'$1()')
			.replace(/~>/g,'=()=>')
			.replace(/([pgs$])(-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'$1($2)')
			.replace(/([_$a-zA-Z]*)“(.*?)”?$/g,'$1(`$2`)')
			.replace(/([_$a-zA-Z]*)‘(.*?)’?$/g,'$1($2)')
			.replace(/([^\\])∞/g,'$1Infinity')
		  .replace(/…/g,'...')
	if(!i.match(/\$[^{]/g))i+=';$()';
	e(i);
}<|endoftext|>


<commit_before>
var request = require('./client')

module.exports = ({request:client}) => async ({provider, input, output}) => {
  if (!provider.response || !provider.response.includes('profile')) {
    return {provider, input, output}
  }

  if (!provider.profile_url) {
    output.profile = {error: 'Grant: No profile URL found!'}
    return {provider, input, output}
  }

  var options = {
    method: 'GET',
    url: provider.profile_url,
    headers: {},
  }

  if (provider.oauth === 2) {
    options.headers.authorization = `Bearer ${output.access_token}`
  }
  else if (provider.oauth === 1) {
    options.oauth = {
      consumer_key: provider.key,
      consumer_secret: provider.secret,
      token: output.access_token,
      token_secret: output.access_secret,
    }
  }

  if (custom[provider.name]) {
    Object.assign(options, custom[provider.name]({provider, output}))
  }

  if (provider.subdomain) {
    options.url = options.url.replace('[subdomain]', provider.subdomain)
  }

  try {
    var {body} = await request({...client, ...options})
    // JSONP
    if (provider.flickr) {
      body = JSON.parse(/^.*\((.*)\)/.exec(body)[1])
    }
    // qq
    if (provider.qq){
      options.url = 'https://graph.qq.com/user/get_user_info'
      body = JSON.parse(/^.*\((.*)\)/.exec(Object.keys(body)[0])[1])
      var res2 = await request({
        ...client,
        ...options,
        qs:{
          access_token: output.access_token,
          oauth_consumer_key: provider.key,
          openid: body.openid
        }
      })
      body = {...body, ...res2.body }
    }

    output.profile = body
  }
  catch (err) {
    output.profile = {error: err.body || err.message}
  }

  return {provider, input, output}
}

var custom = {
  arcgis: () => ({qs: {f: 'json'}}),
  baidu: ({output}) => ({qs: {access_token: output.access_token}}),
  constantcontact: ({provider}) => ({qs: {api_key: provider.key}}),
  deezer: ({output}) => ({qs: {access_token: output.access_token}}),
  disqus: ({provider}) => ({qs: {api_key: provider.key}}),
  dropbox: () => ({method: 'POST'}),
  echosign: ({output}) => ({headers: {'Access-Token': output.access_token}}),
  flickr: ({provider}) => ({qs: {method: 'flickr.urls.getUserProfile', api_key: provider.key, format: 'json'}}),
  foursquare: ({output}) => ({qs: {oauth_token: output.access_token}}),
  getpocket: ({provider, output}) => ({json: {consumer_key: provider.key, access_token: output.access_token}}),
  instagram: ({provider, output}) => /^\d+$/.test(provider.key) ? {qs: {fields: 'id,account_type,username'}} : {url: 'https://api.instagram.com/v1/users/self', qs: {access_token: output.access_token}},
  linkedin: () => ({headers: {'x-li-format': 'json'}}),
  mailchimp: ({output}) => ({qs: {apikey: output.access_token}}),
  meetup: ({output}) => ({qs: {member_id: 'self'}}),
  mixcloud: ({output}) => ({qs: {access_token: output.access_token}}),
  qq: ({output}) => ({qs: {access_token: output.access_token}}),
  shopify: ({output}) => ({headers: {'X-Shopify-Access-Token': output.access_token}}),
  slack: ({output}) => ({qs: {token: output.access_token}}),
  soundcloud: ({output}) => ({qs: {oauth_token: output.access_token}}),
  stackexchange: ({output}) => ({qs: {key: output.access_token}}),
  stocktwits: ({output}) => ({qs: {access_token: output.access_token}}),
  trello: ({output}) => ({qs: {key: output.access_token}}),
  tumblr: ({output}) => ({qs: {api_key: output.access_token}}),
  vk: ({output}) => ({qs: {access_token: output.access_token, v: '5.103'}}),
  weibo: ({output}) => ({qs: {access_token: output.access_token, uid: output.raw.uid}}),
  twitter: ({output}) => ({qs: {user_id: output.raw.user_id}}),
}
<commit_msg>Refactor qq secondary profile request<commit_after>
var request = require('./client')

module.exports = ({request:client}) => async ({provider, input, output}) => {
  if (!provider.response || !provider.response.includes('profile')) {
    return {provider, input, output}
  }

  if (!provider.profile_url) {
    output.profile = {error: 'Grant: No profile URL found!'}
    return {provider, input, output}
  }

  var options = {
    method: 'GET',
    url: provider.profile_url,
    headers: {},
  }

  if (provider.oauth === 2) {
    options.headers.authorization = `Bearer ${output.access_token}`
  }
  else if (provider.oauth === 1) {
    options.oauth = {
      consumer_key: provider.key,
      consumer_secret: provider.secret,
      token: output.access_token,
      token_secret: output.access_secret,
    }
  }

  if (custom[provider.name]) {
    Object.assign(options, custom[provider.name]({provider, output}))
  }

  if (provider.subdomain) {
    options.url = options.url.replace('[subdomain]', provider.subdomain)
  }

  try {
    var {body} = await request({...client, ...options})
    // JSONP
    if (provider.flickr) {
      body = JSON.parse(/^.*\((.*)\)/.exec(body)[1])
    }
    // JSONP + secondary request
    if (provider.qq) {
      body = JSON.parse(/^.*\((.*)\)/.exec(Object.keys(body)[0])[1])
      body = {...body, ...(await request({...client, ...options,
        url: 'https://graph.qq.com/user/get_user_info',
        qs: {
          access_token: output.access_token,
          oauth_consumer_key: provider.key,
          openid: body.openid
        }
      })).body}

    }
    output.profile = body
  }
  catch (err) {
    output.profile = {error: err.body || err.message}
  }

  return {provider, input, output}
}

var custom = {
  arcgis: () => ({qs: {f: 'json'}}),
  baidu: ({output}) => ({qs: {access_token: output.access_token}}),
  constantcontact: ({provider}) => ({qs: {api_key: provider.key}}),
  deezer: ({output}) => ({qs: {access_token: output.access_token}}),
  disqus: ({provider}) => ({qs: {api_key: provider.key}}),
  dropbox: () => ({method: 'POST'}),
  echosign: ({output}) => ({headers: {'Access-Token': output.access_token}}),
  flickr: ({provider}) => ({qs: {method: 'flickr.urls.getUserProfile', api_key: provider.key, format: 'json'}}),
  foursquare: ({output}) => ({qs: {oauth_token: output.access_token}}),
  getpocket: ({provider, output}) => ({json: {consumer_key: provider.key, access_token: output.access_token}}),
  instagram: ({provider, output}) => /^\d+$/.test(provider.key) ? {qs: {fields: 'id,account_type,username'}} : {url: 'https://api.instagram.com/v1/users/self', qs: {access_token: output.access_token}},
  linkedin: () => ({headers: {'x-li-format': 'json'}}),
  mailchimp: ({output}) => ({qs: {apikey: output.access_token}}),
  meetup: ({output}) => ({qs: {member_id: 'self'}}),
  mixcloud: ({output}) => ({qs: {access_token: output.access_token}}),
  qq: ({output}) => ({qs: {access_token: output.access_token}}),
  shopify: ({output}) => ({headers: {'X-Shopify-Access-Token': output.access_token}}),
  slack: ({output}) => ({qs: {token: output.access_token}}),
  soundcloud: ({output}) => ({qs: {oauth_token: output.access_token}}),
  stackexchange: ({output}) => ({qs: {key: output.access_token}}),
  stocktwits: ({output}) => ({qs: {access_token: output.access_token}}),
  trello: ({output}) => ({qs: {key: output.access_token}}),
  tumblr: ({output}) => ({qs: {api_key: output.access_token}}),
  vk: ({output}) => ({qs: {access_token: output.access_token, v: '5.103'}}),
  weibo: ({output}) => ({qs: {access_token: output.access_token, uid: output.raw.uid}}),
  twitter: ({output}) => ({qs: {user_id: output.raw.user_id}}),
}
<|endoftext|>