<commit_before>// @flow
import type {NextConfig} from '../server/config'
import path from 'path'
import webpack from 'webpack'
import resolve from 'resolve'
import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin'
import WriteFilePlugin from 'write-file-webpack-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import WebpackBar from 'webpackbar'
import {getPages} from './webpack/utils'
import PagesPlugin from './webpack/plugins/pages-plugin'
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import NextJsRequireCacheHotReloader from './webpack/plugins/nextjs-require-cache-hot-reloader'
import UnlinkFilePlugin from './webpack/plugins/unlink-file-plugin'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST, DEFAULT_PAGES_DIR, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from '../lib/constants'

// The externals config makes sure that
// on the server side when modules are
// in node_modules they don't get compiled by webpack
function externalsConfig (dir, isServer) {
  const externals = []

  if (!isServer) {
    return externals
  }

  externals.push((context, request, callback) => {
    resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => {
      if (err) {
        return callback()
      }

      // Default pages have to be transpiled
      if (res.match(/node_modules[/\\]next[/\\]dist[/\\]pages/)) {
        return callback()
      }

      // Webpack itself has to be compiled because it doesn't always use module relative paths
      if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
        return callback()
      }

      if (res.match(/node_modules[/\\].*\.js$/)) {
        return callback(null, `commonjs ${request}`)
      }

      callback()
    })
  })

  return externals
}

function optimizationConfig ({dir, dev, isServer, totalPages}) {
  if (isServer) {
    return {
      splitChunks: false,
      minimize: false
    }
  }

  const config: any = {
    runtimeChunk: {
      name: CLIENT_STATIC_FILES_RUNTIME_WEBPACK
    },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false
      }
    }
  }

  if (dev) {
    return config
  }

  // Only enabled in production
  // This logic will create a commons bundle
  // with modules that are used in 50% of all pages
  config.splitChunks.chunks = 'all'
  config.splitChunks.cacheGroups.commons = {
    name: 'commons',
    chunks: 'all',
    minChunks: totalPages > 2 ? totalPages * 0.5 : 2
  }

  return config
}

type BaseConfigContext = {|
  dev: boolean,
  isServer: boolean,
  buildId: string,
  config: NextConfig
|}

export default async function getBaseWebpackConfig (dir: string, {dev = false, isServer = false, buildId, config}: BaseConfigContext) {
  const defaultLoaders = {
    babel: {
      loader: 'next-babel-loader',
      options: {dev, isServer}
    },
    hotSelfAccept: {
      loader: 'hot-self-accept-loader',
      options: {
        include: [
          path.join(dir, 'pages')
        ],
        // All pages are javascript files. So we apply hot-self-accept-loader here to facilitate hot reloading of pages.
        // This makes sure plugins just have to implement `pageExtensions` instead of also implementing the loader
        extensions: new RegExp(`\\.+(${config.pageExtensions.join('|')})$`)
      }
    }
  }

  // Support for NODE_PATH
  const nodePathList = (process.env.NODE_PATH || '')
    .split(process.platform === 'win32' ? ';' : ':')
    .filter((p) => !!p)

  const outputPath = path.join(dir, config.distDir, isServer ? SERVER_DIRECTORY : '')
  const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, buildId, isServer, pageExtensions: config.pageExtensions.join('|')})
  const totalPages = Object.keys(pagesEntries).length
  const clientEntries = !isServer ? {
    // Backwards compatibility
    'main.js': [],
    [CLIENT_STATIC_FILES_RUNTIME_MAIN]: [
      path.join(NEXT_PROJECT_ROOT_DIST, 'client', (dev ? `next-dev` : 'next'))
    ].filter(Boolean)
  } : {}

  let webpackConfig = {
    mode: dev ? 'development' : 'production',
    devtool: dev ? 'cheap-module-source-map' : false,
    name: isServer ? 'server' : 'client',
    cache: true,
    target: isServer ? 'node' : 'web',
    externals: externalsConfig(dir, isServer),
    optimization: optimizationConfig({dir, dev, isServer, totalPages}),
    recordsPath: path.join(outputPath, 'records.json'),
    context: dir,
    // Kept as function to be backwards compatible
    entry: async () => {
      return {
        ...clientEntries,
        // Only _error and _document when in development. The rest is handled by on-demand-entries
        ...pagesEntries
      }
    },
    output: {
      path: outputPath,
      filename: ({chunk}) => {
        // Use `[name]-[chunkhash].js` in production
        if (!dev && (chunk.name === CLIENT_STATIC_FILES_RUNTIME_MAIN || chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK)) {
          return chunk.name.replace(/\.js$/, '-' + chunk.renderedHash + '.js')
        }
        return '[name]'
      },
      libraryTarget: 'commonjs2',
      hotUpdateChunkFilename: 'static/webpack/[id].[hash].hot-update.js',
      hotUpdateMainFilename: 'static/webpack/[hash].hot-update.json',
      // This saves chunks with the name given via `import()`
      chunkFilename: isServer ? `${dev ? '[name]' : '[chunkhash]'}.js` : `static/chunks/${dev ? '[name]' : '[chunkhash]'}.js`,
      strictModuleExceptionHandling: true
    },
    performance: { hints: false },
    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        ...nodePathList // Support for NODE_PATH environment variable
      ],
      alias: {
        next: NEXT_PROJECT_ROOT
      }
    },
    resolveLoader: {
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        path.join(__dirname, 'webpack', 'loaders'), // The loaders Next.js provides
        ...nodePathList // Support for NODE_PATH environment variable
      ]
    },
    module: {
      rules: [
        dev && !isServer && {
          test: defaultLoaders.hotSelfAccept.options.extensions,
          include: defaultLoaders.hotSelfAccept.options.include,
          use: defaultLoaders.hotSelfAccept
        },
        {
          test: /\.(js|jsx)$/,
          include: [dir],
          exclude: /node_modules/,
          use: defaultLoaders.babel
        }
      ].filter(Boolean)
    },
    plugins: [
      // This plugin makes sure `output.filename` is used for entry chunks
      new ChunkNamesPlugin(),
      !isServer && new ReactLoadablePlugin({
        filename: REACT_LOADABLE_MANIFEST
      }),
      new WebpackBar({
        name: isServer ? 'server' : 'client'
      }),
      dev && !isServer && new FriendlyErrorsWebpackPlugin(),
      new webpack.IgnorePlugin(/(precomputed)/, /node_modules.+(elliptic)/),
      // Even though require.cache is server only we have to clear assets from both compilations
      // This is because the client compilation generates the build manifest that's used on the server side
      dev && new NextJsRequireCacheHotReloader(),
      dev && !isServer && new webpack.HotModuleReplacementPlugin(),
      dev && new webpack.NoEmitOnErrorsPlugin(),
      dev && new UnlinkFilePlugin(),
      dev && new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive
      dev && new WriteFilePlugin({
        exitOnErrors: false,
        log: false,
        // required not to cache removed files
        useHashIndex: false
      }),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production')
      }),
      !dev && new webpack.optimize.ModuleConcatenationPlugin(),
      isServer && new PagesManifestPlugin(),
      !isServer && new BuildManifestPlugin(),
      !isServer && new PagesPlugin(),
      isServer && new NextJsSsrImportPlugin(),
      isServer && new NextJsSSRModuleCachePlugin({outputPath})
    ].filter(Boolean)
  }

  if (typeof config.webpack === 'function') {
    webpackConfig = config.webpack(webpackConfig, {dir, dev, isServer, buildId, config, defaultLoaders, totalPages})
  }

  // Backwards compat for `main.js` entry key
  const originalEntry = webpackConfig.entry
  webpackConfig.entry = async () => {
    const entry: any = {...await originalEntry()}

    // Server compilation doesn't have main.js
    if (typeof entry['main.js'] !== 'undefined') {
      entry[CLIENT_STATIC_FILES_RUNTIME_MAIN] = [
        ...entry['main.js'],
        ...entry[CLIENT_STATIC_FILES_RUNTIME_MAIN]
      ]

      delete entry['main.js']
    }

    return entry
  }

  return webpackConfig
}
<commit_msg>Use contenthash instead of chunkhash (#4894)<commit_after>// @flow
import type {NextConfig} from '../server/config'
import path from 'path'
import webpack from 'webpack'
import resolve from 'resolve'
import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin'
import WriteFilePlugin from 'write-file-webpack-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import WebpackBar from 'webpackbar'
import {getPages} from './webpack/utils'
import PagesPlugin from './webpack/plugins/pages-plugin'
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import NextJsRequireCacheHotReloader from './webpack/plugins/nextjs-require-cache-hot-reloader'
import UnlinkFilePlugin from './webpack/plugins/unlink-file-plugin'
import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin'
import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin'
import {SERVER_DIRECTORY, NEXT_PROJECT_ROOT, NEXT_PROJECT_ROOT_NODE_MODULES, NEXT_PROJECT_ROOT_DIST, DEFAULT_PAGES_DIR, REACT_LOADABLE_MANIFEST, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, CLIENT_STATIC_FILES_RUNTIME_MAIN} from '../lib/constants'

// The externals config makes sure that
// on the server side when modules are
// in node_modules they don't get compiled by webpack
function externalsConfig (dir, isServer) {
  const externals = []

  if (!isServer) {
    return externals
  }

  externals.push((context, request, callback) => {
    resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => {
      if (err) {
        return callback()
      }

      // Default pages have to be transpiled
      if (res.match(/node_modules[/\\]next[/\\]dist[/\\]pages/)) {
        return callback()
      }

      // Webpack itself has to be compiled because it doesn't always use module relative paths
      if (res.match(/node_modules[/\\]webpack/) || res.match(/node_modules[/\\]css-loader/)) {
        return callback()
      }

      if (res.match(/node_modules[/\\].*\.js$/)) {
        return callback(null, `commonjs ${request}`)
      }

      callback()
    })
  })

  return externals
}

function optimizationConfig ({dir, dev, isServer, totalPages}) {
  if (isServer) {
    return {
      splitChunks: false,
      minimize: false
    }
  }

  const config: any = {
    runtimeChunk: {
      name: CLIENT_STATIC_FILES_RUNTIME_WEBPACK
    },
    splitChunks: {
      cacheGroups: {
        default: false,
        vendors: false
      }
    }
  }

  if (dev) {
    return config
  }

  // Only enabled in production
  // This logic will create a commons bundle
  // with modules that are used in 50% of all pages
  config.splitChunks.chunks = 'all'
  config.splitChunks.cacheGroups.commons = {
    name: 'commons',
    chunks: 'all',
    minChunks: totalPages > 2 ? totalPages * 0.5 : 2
  }

  return config
}

type BaseConfigContext = {|
  dev: boolean,
  isServer: boolean,
  buildId: string,
  config: NextConfig
|}

export default async function getBaseWebpackConfig (dir: string, {dev = false, isServer = false, buildId, config}: BaseConfigContext) {
  const defaultLoaders = {
    babel: {
      loader: 'next-babel-loader',
      options: {dev, isServer}
    },
    hotSelfAccept: {
      loader: 'hot-self-accept-loader',
      options: {
        include: [
          path.join(dir, 'pages')
        ],
        // All pages are javascript files. So we apply hot-self-accept-loader here to facilitate hot reloading of pages.
        // This makes sure plugins just have to implement `pageExtensions` instead of also implementing the loader
        extensions: new RegExp(`\\.+(${config.pageExtensions.join('|')})$`)
      }
    }
  }

  // Support for NODE_PATH
  const nodePathList = (process.env.NODE_PATH || '')
    .split(process.platform === 'win32' ? ';' : ':')
    .filter((p) => !!p)

  const outputPath = path.join(dir, config.distDir, isServer ? SERVER_DIRECTORY : '')
  const pagesEntries = await getPages(dir, {nextPagesDir: DEFAULT_PAGES_DIR, dev, buildId, isServer, pageExtensions: config.pageExtensions.join('|')})
  const totalPages = Object.keys(pagesEntries).length
  const clientEntries = !isServer ? {
    // Backwards compatibility
    'main.js': [],
    [CLIENT_STATIC_FILES_RUNTIME_MAIN]: [
      path.join(NEXT_PROJECT_ROOT_DIST, 'client', (dev ? `next-dev` : 'next'))
    ].filter(Boolean)
  } : {}

  let webpackConfig = {
    mode: dev ? 'development' : 'production',
    devtool: dev ? 'cheap-module-source-map' : false,
    name: isServer ? 'server' : 'client',
    cache: true,
    target: isServer ? 'node' : 'web',
    externals: externalsConfig(dir, isServer),
    optimization: optimizationConfig({dir, dev, isServer, totalPages}),
    recordsPath: path.join(outputPath, 'records.json'),
    context: dir,
    // Kept as function to be backwards compatible
    entry: async () => {
      return {
        ...clientEntries,
        // Only _error and _document when in development. The rest is handled by on-demand-entries
        ...pagesEntries
      }
    },
    output: {
      path: outputPath,
      filename: ({chunk}) => {
        // Use `[name]-[contenthash].js` in production
        if (!dev && (chunk.name === CLIENT_STATIC_FILES_RUNTIME_MAIN || chunk.name === CLIENT_STATIC_FILES_RUNTIME_WEBPACK)) {
          return chunk.name.replace(/\.js$/, '-' + chunk.contentHash.javascript + '.js')
        }
        return '[name]'
      },
      libraryTarget: 'commonjs2',
      hotUpdateChunkFilename: 'static/webpack/[id].[hash].hot-update.js',
      hotUpdateMainFilename: 'static/webpack/[hash].hot-update.json',
      // This saves chunks with the name given via `import()`
      chunkFilename: isServer ? `${dev ? '[name]' : '[contenthash]'}.js` : `static/chunks/${dev ? '[name]' : '[contenthash]'}.js`,
      strictModuleExceptionHandling: true
    },
    performance: { hints: false },
    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        ...nodePathList // Support for NODE_PATH environment variable
      ],
      alias: {
        next: NEXT_PROJECT_ROOT
      }
    },
    resolveLoader: {
      modules: [
        NEXT_PROJECT_ROOT_NODE_MODULES,
        'node_modules',
        path.join(__dirname, 'webpack', 'loaders'), // The loaders Next.js provides
        ...nodePathList // Support for NODE_PATH environment variable
      ]
    },
    module: {
      rules: [
        dev && !isServer && {
          test: defaultLoaders.hotSelfAccept.options.extensions,
          include: defaultLoaders.hotSelfAccept.options.include,
          use: defaultLoaders.hotSelfAccept
        },
        {
          test: /\.(js|jsx)$/,
          include: [dir],
          exclude: /node_modules/,
          use: defaultLoaders.babel
        }
      ].filter(Boolean)
    },
    plugins: [
      // This plugin makes sure `output.filename` is used for entry chunks
      new ChunkNamesPlugin(),
      !isServer && new ReactLoadablePlugin({
        filename: REACT_LOADABLE_MANIFEST
      }),
      new WebpackBar({
        name: isServer ? 'server' : 'client'
      }),
      dev && !isServer && new FriendlyErrorsWebpackPlugin(),
      new webpack.IgnorePlugin(/(precomputed)/, /node_modules.+(elliptic)/),
      // Even though require.cache is server only we have to clear assets from both compilations
      // This is because the client compilation generates the build manifest that's used on the server side
      dev && new NextJsRequireCacheHotReloader(),
      dev && !isServer && new webpack.HotModuleReplacementPlugin(),
      dev && new webpack.NoEmitOnErrorsPlugin(),
      dev && new UnlinkFilePlugin(),
      dev && new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive
      dev && new WriteFilePlugin({
        exitOnErrors: false,
        log: false,
        // required not to cache removed files
        useHashIndex: false
      }),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production')
      }),
      !dev && new webpack.optimize.ModuleConcatenationPlugin(),
      isServer && new PagesManifestPlugin(),
      !isServer && new BuildManifestPlugin(),
      !isServer && new PagesPlugin(),
      isServer && new NextJsSsrImportPlugin(),
      isServer && new NextJsSSRModuleCachePlugin({outputPath})
    ].filter(Boolean)
  }

  if (typeof config.webpack === 'function') {
    webpackConfig = config.webpack(webpackConfig, {dir, dev, isServer, buildId, config, defaultLoaders, totalPages})
  }

  // Backwards compat for `main.js` entry key
  const originalEntry = webpackConfig.entry
  webpackConfig.entry = async () => {
    const entry: any = {...await originalEntry()}

    // Server compilation doesn't have main.js
    if (typeof entry['main.js'] !== 'undefined') {
      entry[CLIENT_STATIC_FILES_RUNTIME_MAIN] = [
        ...entry['main.js'],
        ...entry[CLIENT_STATIC_FILES_RUNTIME_MAIN]
      ]

      delete entry['main.js']
    }

    return entry
  }

  return webpackConfig
}
<|endoftext|>


<commit_before>jQuery(function ($) {

    $('body.page-find .map-select').click(function () {
        $('body.page-find .map-overlay').css('left', '50%');
    });
    $('body.page-find .map-overlay .map-close').click(function () {
        $('.map-overlay').css('left', '-9000px');
    });

    var latlng = new google.maps.LatLng(46.8, 8.233333); // CH
    var myOptions = {
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        maxZoom: 18,
        minZoom: 5,
        mapTypeControl: false,
        zoom: 8
    };
    var map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);

    var overlay;

    var control = new GeometryControl(map, function () {
        if (overlay) {
            overlay.overlay.setMap(null);
        }
    });

    control.addPolygon(function () {

        var geo = [];
        control.overlay.overlay.getPath().forEach(function (position) {
            geo.push(position.toUrlValue());
        });

        var parameters = Drupal.settings.find.parameters;
        parameters['geo'] = geo;

        var url = Drupal.settings.find.url + '?' + $.param(parameters);
        window.location.href = url;

        $('.map-overlay').css('left', '-9000px');
    });

    // add overlay if geo is set
    if (Drupal.settings.find.geo.length > 1) {

        var path = [];
        for (var i = 0, l = Drupal.settings.find.geo.length; i < l; i++) {
            var values = Drupal.settings.find.geo[i].split(',');
            path.push(new google.maps.LatLng(values[0], values[1]));
        }

        overlay = new Polygon(map);
        overlay.overlay.setPath(path);
        map.fitBounds(overlay.getBounds());
    }
});
<commit_msg>Don't hide overlay<commit_after>jQuery(function ($) {

    $('body.page-find .map-select').click(function () {
        $('body.page-find .map-overlay').css('left', '50%');
    });
    $('body.page-find .map-overlay .map-close').click(function () {
        $('.map-overlay').css('left', '-9000px');
    });

    var latlng = new google.maps.LatLng(46.8, 8.233333); // CH
    var myOptions = {
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        maxZoom: 18,
        minZoom: 5,
        mapTypeControl: false,
        zoom: 8
    };
    var map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);

    var overlay;

    var control = new GeometryControl(map, function () {
        if (overlay) {
            overlay.overlay.setMap(null);
        }
    });

    control.addPolygon(function () {

        // don't hide polygon
        control.overlay.overlay.setMap(map);

        var geo = [];
        control.overlay.overlay.getPath().forEach(function (position) {
            geo.push(position.toUrlValue());
        });

        var parameters = Drupal.settings.find.parameters;
        parameters['geo'] = geo;

        var url = Drupal.settings.find.url + '?' + $.param(parameters);
        window.location.href = url;
    });

    // add overlay if geo is set
    if (Drupal.settings.find.geo.length > 1) {

        var path = [];
        for (var i = 0, l = Drupal.settings.find.geo.length; i < l; i++) {
            var values = Drupal.settings.find.geo[i].split(',');
            path.push(new google.maps.LatLng(values[0], values[1]));
        }

        overlay = new Polygon(map);
        overlay.overlay.setPath(path);
        map.fitBounds(overlay.getBounds());
    }
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var pinf = require( 'const-pinf-float32' );
var ninf = require( 'const-ninf-float32' );
var round = require( 'math-round' );
var pow = require( 'math-power' );
var bits = require( 'math-float32-bits' );
var exponent = require( './../lib' );

// VARIABLES //

var BIAS = 127;

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( typeof exponent === 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns a number', function test( t ) {
	t.equal( typeof exponent(3.14e30), 'number', 'returns a number' );
	t.end();
});

tape( 'the function returns an integer corresponding to the unbiased exponent of a single-precision floating-point number', function test( t ) {
	var expected;
	var actual;
	var sign;
	var frac;
	var exp;
	var x;
	var b;
	var i;

	for ( i = 0; i < 5e3; i++ ) {
		if ( Math.random() < 0.5 ) {
			sign = -1;
		} else {
			sign = 1;
		}
		frac = Math.random() * 10;
		exp = round( Math.random()*44 ) - 22;
		x = sign * frac * pow( 10, exp );

		b = bits( x );
		expected = parseInt( b.substring( 1, 9 ), 2 ) - BIAS;

		actual = exponent( x );
		t.equal( actual, expected, 'returns the unbiased exponent for ' + x );

	}
	t.end();
});

tape( 'the function returns the unbiased exponent for `+-0`', function test( t ) {
	t.equal( exponent( 0 ), -BIAS, 'returns -127' );
	t.equal( exponent( -0 ), -BIAS, 'returns -127' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `+infinity`', function test( t ) {
	t.equal( exponent( pinf ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `-infinity`', function test( t ) {
	t.equal( exponent( ninf ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `NaN`', function test( t ) {
	t.equal( exponent( NaN ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for subnormals', function test( t ) {
	t.equal( exponent( 3.14e-42 ), -BIAS, 'returns -127' );
	t.end();
});
<commit_msg>Make tests explicitly convert to float32<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var pinf = require( 'const-pinf-float32' );
var ninf = require( 'const-ninf-float32' );
var round = require( 'math-round' );
var pow = require( 'math-power' );
var toFloat32 = require( 'float64-to-float32' );
var bits = require( 'math-float32-bits' );
var exponent = require( './../lib' );

// VARIABLES //

var BIAS = 127;

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( typeof exponent === 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns a number', function test( t ) {
	t.equal( typeof exponent( toFloat32( 3.14e30 ) ), 'number', 'returns a number' );
	t.end();
});

tape( 'the function returns an integer corresponding to the unbiased exponent of a single-precision floating-point number', function test( t ) {
	var expected;
	var actual;
	var sign;
	var frac;
	var exp;
	var x;
	var b;
	var i;

	for ( i = 0; i < 5e3; i++ ) {
		if ( Math.random() < 0.5 ) {
			sign = -1;
		} else {
			sign = 1;
		}
		frac = Math.random() * 10;
		exp = round( Math.random()*44 ) - 22;
		x = sign * frac * pow( 10, exp );

		b = bits( x );
		expected = parseInt( b.substring( 1, 9 ), 2 ) - BIAS;

		actual = exponent( toFloat32( x ) );
		t.equal( actual, expected, 'returns the unbiased exponent for ' + x );

	}
	t.end();
});

tape( 'the function returns the unbiased exponent for `+-0`', function test( t ) {
	t.equal( exponent( 0 ), -BIAS, 'returns -127' );
	t.equal( exponent( -0 ), -BIAS, 'returns -127' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `+infinity`', function test( t ) {
	t.equal( exponent( pinf ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `-infinity`', function test( t ) {
	t.equal( exponent( ninf ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for `NaN`', function test( t ) {
	t.equal( exponent( NaN ), BIAS+1, 'returns 128' );
	t.end();
});

tape( 'the function returns the unbiased exponent for subnormals', function test( t ) {
	t.equal( exponent( toFloat32( 3.14e-42 ) ), -BIAS, 'returns -127' );
	t.end();
});
<|endoftext|>


<commit_before>/*!
 * Escaper
 * https://github.com/kobezzza/Escaper
 *
 * Released under the MIT license
 * https://github.com/kobezzza/Escaper/blob/master/LICENSE
 */

var Escaper = {
	VERSION: [2, 0, 4]
};

var isNode = false;

try {
	isNode = 'object' === typeof process && Object.prototype.toString.call(process) === '[object process]';

} catch (ignore) {

}

/* istanbul ignore next */
if (isNode) {
	module['exports'] =
		exports = Escaper;

} else {
	global.Escaper = Escaper;
}

var escapeMap = {
	'"': true,
	"'" : true,
	'/': true,
	'`': true
};

var sCommentsMap = {
	'//': true
};

var mCommentsMap = {
	'/*': true,
	'/**': true,
	'/*!': true
};

var keyArr = [],
	finalMap = {};

for (let key in escapeMap) {
	/* istanbul ignore if */
	if (!escapeMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

for (let key in sCommentsMap) {
	/* istanbul ignore if */
	if (!sCommentsMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

for (let key in mCommentsMap) {
	/* istanbul ignore if */
	if (!mCommentsMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

var rgxpFlagsMap = {
	'g': true,
	'm': true,
	'i': true,
	'y': true,
	'u': true
};

var rgxpFlags = [];
for (let key in rgxpFlagsMap) {
	/* istanbul ignore if */
	if (!rgxpFlagsMap.hasOwnProperty(key)) {
		continue;
	}

	rgxpFlags.push(key);
}

var escapeEndMap = {
	'-': true,
	'+': true,
	'*': true,
	'%': true,
	'~': true,
	'>': true,
	'<': true,
	'^': true,
	',': true,
	';': true,
	'=': true,
	'|': true,
	'&': true,
	'!': true,
	'?': true,
	':': true,
	'(': true,
	'{': true,
	'[': true
};

var escapeEndWordMap = {
	'typeof': true,
	'void': true,
	'instanceof': true,
	'delete': true,
	'in': true,
	'new': true
};

var cache = {},
	content = [];

/**
 * @param {!Object} obj
 * @param {!Object} p
 * @param {(boolean|number)} val
 */
function mix(obj, p, val) {
	for (let key in obj) {
		/* istanbul ignore if */
		if (!obj.hasOwnProperty(key)) {
			continue;
		}

		if (key in p === false) {
			p[key] = val;
		}
	}
}

/**
 * Стек содержимого
 * @type {!Array}
 */
Escaper.quotContent = content;

var uSRgxp = /[^\s\/]/,
	wRgxp = /[a-z]/,
	sRgxp = /\s/,
	nRgxp = /\r|\n/;

var symbols,
	snakeskinRgxp;

Escaper.snakeskinRgxp = Escaper.snakeskinRgxp || null;
Escaper.symbols = Escaper.symbols || null;

/**
 * Заметить блоки вида ' ... ', " ... ", ` ... `, / ... /, // ..., /* ... *\/ на
 * __ESCAPER_QUOT__номер_ в указанной строке
 *
 * @param {string} str - исходная строка
 * @param {(Object|boolean)=} [opt_withCommentsOrParams=false] - таблица вырезаемых последовательностей:
 *
 *     (если установить значение параметру -1, то он будет полностью вырезаться,
 *     т.е. без возможности обратной замены, иначе true/false - включить/исключить последовательность)
 *
 *     *) @all - специальная команда для выделения всех последовательностей
 *     *) @comments - специальная команда для выделения всех видов комментариев
 *     *) @literals - специальная команда для выделения литералов строк и регулярных выражений
 *     *) `
 *     *) '
 *     *) "
 *     *) /
 *     *) //
 *     *) /*
 *     *) /**
 *     *) /*!
 *
 *     ИЛИ если логическое значение, то вырезаются литералы с комментариями (true) / литералы (false)
 *
 * @param {Array=} [opt_quotContent=Escaper.quotContent] - стек содержимого
 * @param {?boolean=} [opt_snakeskin] - если true, то при экранировании учитываются конструкции Snakeskin
 * @return {string}
 */
Escaper.replace = function (str, opt_withCommentsOrParams, opt_quotContent, opt_snakeskin) {
	symbols = symbols ||
		Escaper.symbols ||
		Escaper['symbols'] ||
		'a-z';

	snakeskinRgxp = snakeskinRgxp ||
		Escaper.snakeskinRgxp ||
		Escaper['snakeskinRgxp'] ||
		new RegExp(`[!$${symbols}_]`, 'i');

	var isObj = opt_withCommentsOrParams instanceof Object;
	var p = isObj ?
		Object(opt_withCommentsOrParams) : {};

	var withComments = false;
	if (typeof opt_withCommentsOrParams === 'boolean') {
		withComments = Boolean(opt_withCommentsOrParams);
	}

	if ('@comments' in p) {
		mix(mCommentsMap, p, p['@comments']);
		mix(sCommentsMap, p, p['@comments']);
		delete p['@comments'];
	}

	if ('@literals' in p) {
		mix(escapeMap, p, p['@literals']);
		delete p['@literals'];
	}

	if ('@all' in p) {
		mix(finalMap, p, p['@all']);
		delete p['@all'];
	}

	var cacheKey = '';
	for (let i = -1; ++i < keyArr.length;) {
		let el = keyArr[i];

		if (mCommentsMap[el] || sCommentsMap[el]) {
			p[el] = withComments || p[el];

		} else {
			p[el] = p[el] || !isObj;
		}

		cacheKey += `${p[el]},`;
	}

	var initStr = str;
	var stack = opt_quotContent ||
		content;

	if (stack === content && cache[cacheKey] && cache[cacheKey][initStr]) {
		return cache[cacheKey][initStr];
	}

	var begin = false,
		end = true;

	var escape = false,
		comment = false;

	var selectionStart = 0,
		block = false;

	var templateVar = 0,
		filterStart = false;

	var cut,
		label;

	var part = '',
		rPart = '';

	for (let i = -1; ++i < str.length;) {
		let el = str.charAt(i),
			next = str.charAt(i + 1);

		let word = str.substr(i, 2),
			extWord = str.substr(i, 3);

		if (!comment) {
			if (!begin) {
				if (el === '/') {
					if (sCommentsMap[word] || mCommentsMap[word]) {
						if (sCommentsMap[extWord] || mCommentsMap[extWord]) {
							comment = extWord;

						} else {
							comment = word;
						}
					}

					if (comment) {
						selectionStart = i;
						continue;
					}
				}

				if (escapeEndMap[el] || escapeEndWordMap[rPart]) {
					end = true;
					rPart = '';

				} else if (uSRgxp.test(el)) {
					end = false;
				}

				if (wRgxp.test(el)) {
					part += el;

				} else {
					rPart = part;
					part = '';
				}

				let skip = false;
				if (opt_snakeskin) {
					if (el === '|' && snakeskinRgxp.test(next)) {
						filterStart = true;
						end = false;
						skip = true;

					} else if (filterStart && sRgxp.test(el)) {
						filterStart = false;
						end = true;
						skip = true;
					}
				}

				if (!skip) {
					if (escapeEndMap[el]) {
						end = true;

					} else if (uSRgxp.test(el)) {
						end = false;
					}
				}
			}

			// Блоки [] внутри регулярного выражения
			if (begin === '/' && !escape) {
				if (el === '[') {
					block = true;

				} else if (el === ']') {
					block = false;
				}
			}

			if (!begin && templateVar) {
				if (el === '}') {
					templateVar--;

				} else if (el === '{') {
					templateVar++;
				}

				if (!templateVar) {
					el = '`';
				}
			}

			if (begin === '`' && !escape && word === '${') {
				el = '`';
				i++;
				templateVar++;
			}

			if (finalMap[el] && (el !== '/' || end) && !begin) {
				begin = el;
				selectionStart = i;

			} else if (begin && (el === '\\' || escape)) {
				escape = !escape;

			} else if (finalMap[el] && begin === el && !escape && (begin !== '/' || !block)) {
				if (el === '/') {
					for (let j = -1; ++j < rgxpFlags.length;) {
						if (rgxpFlagsMap[str.charAt(i + 1)]) {
							i++;
						}
					}
				}

				begin = false;
				end = false;

				if (p[el]) {
					cut = str.substring(selectionStart, i + 1);

					if (p[el] === -1) {
						label = '';

					} else {
						label = `__ESCAPER_QUOT__${stack.length}_`;
						stack.push(cut);
					}

					str = str.substring(0, selectionStart) + label + str.substring(i + 1);
					i += label.length - cut.length;
				}
			}

		} else if ((nRgxp.test(next) && sCommentsMap[comment]) ||
			(mCommentsMap[el + str.charAt(i - 1)] && i - selectionStart > 2 && mCommentsMap[comment])

		) {
			if (p[comment]) {
				cut = str.substring(selectionStart, i + 1);

				if (p[comment] === -1) {
					label = '';

				} else {
					label = `__ESCAPER_QUOT__${stack.length}_`;
					stack.push(cut);
				}

				str = str.substring(0, selectionStart) + label + str.substring(i + 1);
				i += label.length - cut.length;
			}

			comment = false;
		}
	}

	if (stack === content) {
		cache[cacheKey] = cache[cacheKey] || {};
		cache[cacheKey][initStr] = str;
	}

	return str;
};

var pasteRgxp = /__ESCAPER_QUOT__(\d+)_/g;

/**
 * Заметить __ESCAPER_QUOT__номер_ в указанной строке на реальное содержимое
 *
 * @param {string} str - исходная строка
 * @param {Array=} [opt_quotContent=Escaper.quotContent] - стек содержимого
 * @return {string}
 */
Escaper.paste = function (str, opt_quotContent) {
	var stack = opt_quotContent || content;
	return str.replace(pasteRgxp, (sstr, pos) => stack[pos]);
};
<commit_msg>Рефакторинг<commit_after>var Escaper = {
	VERSION: [2, 0, 5]
};

var IS_NODE = false;

try {
	IS_NODE = 'object' === typeof process && Object.prototype.toString.call(process) === '[object process]';

} catch (ignore) {

}

/* istanbul ignore next */
if (IS_NODE) {
	module.exports =
		exports = Escaper;

} else {
	global.Escaper = Escaper;
}

var escapeMap = {
	'"': true,
	"'" : true,
	'/': true,
	'`': true
};

var sCommentsMap = {
	'//': true
};

var mCommentsMap = {
	'/*': true,
	'/**': true,
	'/*!': true
};

var keyArr = [],
	finalMap = {};

for (let key in escapeMap) {
	/* istanbul ignore if */
	if (!escapeMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

for (let key in sCommentsMap) {
	/* istanbul ignore if */
	if (!sCommentsMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

for (let key in mCommentsMap) {
	/* istanbul ignore if */
	if (!mCommentsMap.hasOwnProperty(key)) {
		continue;
	}

	keyArr.push(key);
	finalMap[key] = true;
}

var rgxpFlagsMap = {
	'g': true,
	'm': true,
	'i': true,
	'y': true,
	'u': true
};

var rgxpFlags = [];
for (let key in rgxpFlagsMap) {
	/* istanbul ignore if */
	if (!rgxpFlagsMap.hasOwnProperty(key)) {
		continue;
	}

	rgxpFlags.push(key);
}

var escapeEndMap = {
	'-': true,
	'+': true,
	'*': true,
	'%': true,
	'~': true,
	'>': true,
	'<': true,
	'^': true,
	',': true,
	';': true,
	'=': true,
	'|': true,
	'&': true,
	'!': true,
	'?': true,
	':': true,
	'(': true,
	'{': true,
	'[': true
};

var escapeEndWordMap = {
	'typeof': true,
	'void': true,
	'instanceof': true,
	'delete': true,
	'in': true,
	'new': true
};

var cache = {},
	content = [];

/**
 * @param {!Object} obj
 * @param {!Object} p
 * @param {(boolean|number)} val
 */
function mix(obj, p, val) {
	for (let key in obj) {
		/* istanbul ignore if */
		if (!obj.hasOwnProperty(key)) {
			continue;
		}

		if (key in p === false) {
			p[key] = val;
		}
	}
}

/**
 * Стек содержимого
 * @type {!Array}
 */
Escaper.quotContent = content;

var uSRgxp = /[^\s\/]/,
	wRgxp = /[a-z]/,
	sRgxp = /\s/,
	nRgxp = /\r|\n/;

var symbols,
	snakeskinRgxp;

Escaper.snakeskinRgxp = Escaper.snakeskinRgxp || null;
Escaper.symbols = Escaper.symbols || null;

/**
 * Заметить блоки вида ' ... ', " ... ", ` ... `, / ... /, // ..., /* ... *\/ на
 * __ESCAPER_QUOT__номер_ в указанной строке
 *
 * @param {string} str - исходная строка
 * @param {(Object|boolean)=} [opt_withCommentsOrParams=false] - таблица вырезаемых последовательностей:
 *
 *     (если установить значение параметру -1, то он будет полностью вырезаться,
 *     т.е. без возможности обратной замены, иначе true/false - включить/исключить последовательность)
 *
 *     *) @all - специальная команда для выделения всех последовательностей
 *     *) @comments - специальная команда для выделения всех видов комментариев
 *     *) @literals - специальная команда для выделения литералов строк и регулярных выражений
 *     *) `
 *     *) '
 *     *) "
 *     *) /
 *     *) //
 *     *) /*
 *     *) /**
 *     *) /*!
 *
 *     ИЛИ если логическое значение, то вырезаются литералы с комментариями (true) / литералы (false)
 *
 * @param {Array=} [opt_quotContent=Escaper.quotContent] - стек содержимого
 * @param {?boolean=} [opt_snakeskin] - если true, то при экранировании учитываются конструкции Snakeskin
 * @return {string}
 */
Escaper.replace = function (str, opt_withCommentsOrParams, opt_quotContent, opt_snakeskin) {
	symbols = symbols ||
		Escaper.symbols ||
		Escaper['symbols'] ||
		'a-z';

	snakeskinRgxp = snakeskinRgxp ||
		Escaper.snakeskinRgxp ||
		Escaper['snakeskinRgxp'] ||
		new RegExp(`[!$${symbols}_]`, 'i');

	var isObj = opt_withCommentsOrParams instanceof Object;
	var p = isObj ?
		Object(opt_withCommentsOrParams) : {};

	var withComments = false;
	if (typeof opt_withCommentsOrParams === 'boolean') {
		withComments = Boolean(opt_withCommentsOrParams);
	}

	if ('@comments' in p) {
		mix(mCommentsMap, p, p['@comments']);
		mix(sCommentsMap, p, p['@comments']);
		delete p['@comments'];
	}

	if ('@literals' in p) {
		mix(escapeMap, p, p['@literals']);
		delete p['@literals'];
	}

	if ('@all' in p) {
		mix(finalMap, p, p['@all']);
		delete p['@all'];
	}

	var cacheKey = '';
	for (let i = -1; ++i < keyArr.length;) {
		let el = keyArr[i];

		if (mCommentsMap[el] || sCommentsMap[el]) {
			p[el] = withComments || p[el];

		} else {
			p[el] = p[el] || !isObj;
		}

		cacheKey += `${p[el]},`;
	}

	var initStr = str;
	var stack = opt_quotContent ||
		content;

	if (stack === content && cache[cacheKey] && cache[cacheKey][initStr]) {
		return cache[cacheKey][initStr];
	}

	var begin = false,
		end = true;

	var escape = false,
		comment = false;

	var selectionStart = 0,
		block = false;

	var templateVar = 0,
		filterStart = false;

	var cut,
		label;

	var part = '',
		rPart = '';

	for (let i = -1; ++i < str.length;) {
		let el = str.charAt(i),
			next = str.charAt(i + 1);

		let word = str.substr(i, 2),
			extWord = str.substr(i, 3);

		if (!comment) {
			if (!begin) {
				if (el === '/') {
					if (sCommentsMap[word] || mCommentsMap[word]) {
						if (sCommentsMap[extWord] || mCommentsMap[extWord]) {
							comment = extWord;

						} else {
							comment = word;
						}
					}

					if (comment) {
						selectionStart = i;
						continue;
					}
				}

				if (escapeEndMap[el] || escapeEndWordMap[rPart]) {
					end = true;
					rPart = '';

				} else if (uSRgxp.test(el)) {
					end = false;
				}

				if (wRgxp.test(el)) {
					part += el;

				} else {
					rPart = part;
					part = '';
				}

				let skip = false;
				if (opt_snakeskin) {
					if (el === '|' && snakeskinRgxp.test(next)) {
						filterStart = true;
						end = false;
						skip = true;

					} else if (filterStart && sRgxp.test(el)) {
						filterStart = false;
						end = true;
						skip = true;
					}
				}

				if (!skip) {
					if (escapeEndMap[el]) {
						end = true;

					} else if (uSRgxp.test(el)) {
						end = false;
					}
				}
			}

			// Блоки [] внутри регулярного выражения
			if (begin === '/' && !escape) {
				if (el === '[') {
					block = true;

				} else if (el === ']') {
					block = false;
				}
			}

			if (!begin && templateVar) {
				if (el === '}') {
					templateVar--;

				} else if (el === '{') {
					templateVar++;
				}

				if (!templateVar) {
					el = '`';
				}
			}

			if (begin === '`' && !escape && word === '${') {
				el = '`';
				i++;
				templateVar++;
			}

			if (finalMap[el] && (el !== '/' || end) && !begin) {
				begin = el;
				selectionStart = i;

			} else if (begin && (el === '\\' || escape)) {
				escape = !escape;

			} else if (finalMap[el] && begin === el && !escape && (begin !== '/' || !block)) {
				if (el === '/') {
					for (let j = -1; ++j < rgxpFlags.length;) {
						if (rgxpFlagsMap[str.charAt(i + 1)]) {
							i++;
						}
					}
				}

				begin = false;
				end = false;

				if (p[el]) {
					cut = str.substring(selectionStart, i + 1);

					if (p[el] === -1) {
						label = '';

					} else {
						label = `__ESCAPER_QUOT__${stack.length}_`;
						stack.push(cut);
					}

					str = str.substring(0, selectionStart) + label + str.substring(i + 1);
					i += label.length - cut.length;
				}
			}

		} else if ((nRgxp.test(next) && sCommentsMap[comment]) ||
			(mCommentsMap[el + str.charAt(i - 1)] && i - selectionStart > 2 && mCommentsMap[comment])

		) {
			if (p[comment]) {
				cut = str.substring(selectionStart, i + 1);

				if (p[comment] === -1) {
					label = '';

				} else {
					label = `__ESCAPER_QUOT__${stack.length}_`;
					stack.push(cut);
				}

				str = str.substring(0, selectionStart) + label + str.substring(i + 1);
				i += label.length - cut.length;
			}

			comment = false;
		}
	}

	if (stack === content) {
		cache[cacheKey] = cache[cacheKey] || {};
		cache[cacheKey][initStr] = str;
	}

	return str;
};

var pasteRgxp = /__ESCAPER_QUOT__(\d+)_/g;

/**
 * Заметить __ESCAPER_QUOT__номер_ в указанной строке на реальное содержимое
 *
 * @param {string} str - исходная строка
 * @param {Array=} [opt_quotContent=Escaper.quotContent] - стек содержимого
 * @return {string}
 */
Escaper.paste = function (str, opt_quotContent) {
	var stack = opt_quotContent || content;
	return str.replace(pasteRgxp, (sstr, pos) => stack[pos]);
};
<|endoftext|>


<commit_before>const _ = require('lodash');
const qs = require('qs');
const request = require('request-promise');
const moment = require('moment');
const Provider = require('./provider.js');
const pokemonNames = require('../pokemon_names.js');

class Poke5566 extends Provider {
    constructor(config) {
        super(config);
        this._deviceId = '';
        this._url = 'https://poke5566.com/pokemons';
        this._ttl = 15 * 60 * 1000;
        this._filteredPokemonIds = config.filteredPokemonIds ? config.filteredPokemonIds.sort((a,b) => a-b) : null;
    }

    init() {
        return Promise.resolve();
    }

    getPokemons() {
        const query = {
            lat0: this._config.maxLatitude,
            lng0: this._config.maxLongitude,
            lat1: this._config.minLatitude,
            lng1: this._config.minLongitude,
        };
        const queryString = '?' + qs.stringify(query);

        return request(this._url + queryString).then(this._processData.bind(this));
    }

    _processData(body) {
        let entries = JSON.parse(body).pokemons;
        let filtered = _.filter(entries, (o) => {
            if (this._filteredPokemonIds && _.sortedIndexOf(this._filteredPokemonIds, o.id) == -1) {
                return false;
            }
            return true;
        });
        let processed = filtered.map((entry_) => {
            let entry = {};
            let diff = moment(entry_.time + this._ttl).diff(moment());
            entry.latitude = entry_.lat;
            entry.longitude = entry_.lng;
            entry.pokemonId = entry_.id;
            entry.pokemonName = pokemonNames[entry_.id];
            entry.remainingTime = moment.utc(diff);
            entry.until = moment().milliseconds(diff);
            entry.direction = 'https://www.google.com/maps/dir/Current+Location/' + entry_.lat + ',' + entry_.lng;
            entry.uniqueId = `${entry_.id}-${entry_.time}`;
            return entry;
        });
        return processed;
    }
}

module.exports = Poke5566;
<commit_msg>Update poke5566<commit_after>const _ = require('lodash');
const qs = require('qs');
const request = require('request-promise');
const moment = require('moment');
const Provider = require('./provider.js');
const pokemonNames = require('../pokemon_names.js');

class Poke5566 extends Provider {
    constructor(config) {
        super(config);
        this._deviceId = '';
        this._url = 'https://poke5566.com/pokemons';
        this._ttl = 15 * 60 * 1000;
        this._filteredPokemonIds = config.filteredPokemonIds ? config.filteredPokemonIds.sort((a,b) => a-b) : null;
    }

    init() {
        return Promise.resolve();
    }

    getPokemons() {
        const query = {
            latBL: this._config.maxLatitude,
            lngBL: this._config.maxLongitude,
            latTR: this._config.minLatitude,
            lngTR: this._config.minLongitude,
        };
        const queryString = '?' + qs.stringify(query);
        const options = {
            url: this._url + queryString,
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Referer': 'https://poke5566.com/',
                'Cookie': '_ga=GA1.2.144174314.1472498477;',
                'User-Agent': 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16'
            }
        };

        return request(options).then(this._processData.bind(this));
    }

    _processData(body) {
        let entries = JSON.parse(body).pokemons;
        let filtered = _.filter(entries, (o) => {
            if (this._filteredPokemonIds && _.sortedIndexOf(this._filteredPokemonIds, o.id) == -1) {
                return false;
            }
            return true;
        });
        let processed = filtered.map((entry_) => {
            let entry = {};
            let diff = moment(entry_.time).diff(moment());
            entry.latitude = entry_.lat;
            entry.longitude = entry_.lng;
            entry.pokemonId = entry_.id;
            entry.pokemonName = pokemonNames[entry_.id];
            entry.remainingTime = moment.utc(diff);
            entry.until = moment(entry_.time);
            entry.direction = 'https://www.google.com/maps/dir/Current+Location/' + entry_.lat + ',' + entry_.lng;
            entry.uniqueId = `${entry_.id}-${entry_.time}`;
            return entry;
        });
        return processed;
    }
}

module.exports = Poke5566;
<|endoftext|>


<commit_before>const { assert } = require('chai');

const { getChart } = require('../billboard-top-100.js');
const { listCharts } = require('../billboard-top-100.js');

describe('getChart()', () => {
  describe('get a past chart (hot-100: week of 2016-11-19)', () => {
    it('should callback with the hot-100 chart for the week of 2016-11-19', (done) => {
      getChart('hot-100', '2016-11-19', (err, chart) => {
        if (err) done(err);

        assert.equal(chart.week, '2016-11-19', 'chart week is `2016-11-19`');
        assert.equal(chart.previousWeek.date, '2016-11-12', 'date of chart\'s previous week is `2016-11-12`');
        assert.equal(chart.previousWeek.url, 'http://www.billboard.com/charts/hot-100/2016-11-12', 'url of chart\'s previous week is correct');
        assert.equal(chart.nextWeek.date, '2016-11-26', 'date of chart\'s next week is `2016-11-26`');
        assert.equal(chart.nextWeek.url, 'http://www.billboard.com/charts/hot-100/2016-11-26', 'url of chart\'s next week is correct');

        assert.lengthOf(chart.songs, 100, 'chart has 100 songs');

        assert.deepEqual(chart.songs[0], {
          rank: 1,
          title: 'Closer',
          artist: 'The Chainsmokers Featuring Halsey',
          cover: 'https://charts-static.billboard.com/img/2016/08/the-chainsmokers-9iv.jpg',
          position: { positionLastWeek: 1, peakPosition: 1, weeksOnChart: 14 },
        }, 'first song is correct');

        assert.deepEqual(chart.songs[37], {
          rank: 38,
          title: 'Tiimmy Turner',
          artist: 'Desiigner',
          cover:
           'https://charts-static.billboard.com/img/2016/08/desiigner-l9j.jpg',
          position: { positionLastWeek: 37, peakPosition: 34, weeksOnChart: 15 },
        }, 'arbitrary (38th) song is correct');

        assert.deepEqual(chart.songs[99], {
          rank: 100,
          title: 'Cool Girl',
          artist: 'Tove Lo',
          cover: 'https://charts-static.billboard.com/img/2016/08/tove-lo-vxl.jpg',
          position: { positionLastWeek: NaN, peakPosition: 84, weeksOnChart: 5 },
        }, 'last song is correct');

        done();
      });
    }).timeout(5000);
  });

  describe('get a current chart (hot-100)', () => {
    it('should callback with the hot-100 chart for this week', (done) => {
      getChart('hot-100', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 100, 'chart has 100 songs');

        const firstSong = chart.songs[0];
        assert(firstSong, 'first song is non-null and defined');
        assert(firstSong.rank, 'first song has rank');
        assert(firstSong.title, 'first song has title');
        assert(firstSong.artist, 'first song has artist');
        assert(firstSong.position, 'first song has non-null and defined position');
        assert(firstSong.position.peakPosition, 'first song has peak position');
        assert(firstSong.position.weeksOnChart, 'first song has weeks on chart');

        const arbitrarySong = chart.songs[38];
        assert(arbitrarySong, 'arbitrary (38th) song is non-null and defined');
        assert(arbitrarySong.rank, 'arbitrary (38th) song has rank');
        assert(arbitrarySong.title, 'arbitrary (38th) song has title');
        assert(arbitrarySong.artist, 'arbitrary (38th) song has artist');
        assert(arbitrarySong.cover, 'arbitrary (38th) song has cover');
        assert(arbitrarySong.position, 'arbitrary (38th) song has non-null and defined position');
        assert(arbitrarySong.position.peakPosition, 'arbitrary (38th) song has peak position');
        assert(arbitrarySong.position.weeksOnChart, 'arbitrary (38th) song has weeks on chart');

        const lastSong = chart.songs[99];
        assert(lastSong, 'last song is non-null and defined');
        assert(lastSong.rank, 'last song has rank');
        assert(lastSong.title, 'last song has title');
        assert(lastSong.artist, 'last song has artist');
        assert(lastSong.cover, 'last song has cover');
        assert(lastSong.position, 'last song has non-null and defined position');
        assert(lastSong.position.peakPosition, 'last song has peak position');
        assert(lastSong.position.weeksOnChart, 'last song has weeks on chart');

        done();
      });
    }).timeout(5000);
  });

  describe('get a current chart (latin-songs)', () => {
    it('should callback with the latin-songs chart for this week', (done) => {
      getChart('latin-songs', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 50, 'chart has 50 songs');

        const firstSong = chart.songs[0];
        assert(firstSong, 'first song is non-null and defined');
        assert(firstSong.rank, 'first song has rank');
        assert(firstSong.title, 'first song has title');
        assert(firstSong.artist, 'first song has artist');
        assert(firstSong.position, 'first song has non-null and defined position');
        assert(firstSong.position.peakPosition, 'first song has peak position');
        assert(firstSong.position.weeksOnChart, 'first song has weeks on chart');

        const arbitrarySong = chart.songs[38];
        assert(arbitrarySong, 'arbitrary (38th) song is non-null and defined');
        assert(arbitrarySong.rank, 'arbitrary (38th) song has rank');
        assert(arbitrarySong.title, 'arbitrary (38th) song has title');
        assert(arbitrarySong.artist, 'arbitrary (38th) song has artist');
        assert(arbitrarySong.cover, 'arbitrary (38th) song has cover');
        assert(arbitrarySong.position, 'arbitrary (38th) song has non-null and defined position');
        assert(arbitrarySong.position.peakPosition, 'arbitrary (38th) song has peak position');
        assert(arbitrarySong.position.weeksOnChart, 'arbitrary (38th) song has weeks on chart');

        const lastSong = chart.songs[49];
        assert(lastSong, 'last song is non-null and defined');
        assert(lastSong.rank, 'last song has rank');
        assert(lastSong.title, 'last song has title');
        assert(lastSong.artist, 'last song has artist');
        assert(lastSong.cover, 'last song has cover');
        assert(lastSong.position, 'last song has non-null and defined position');
        assert(lastSong.position.peakPosition, 'last song has peak position');
        assert(lastSong.position.weeksOnChart, 'last song has weeks on chart');

        done();
      });
    }).timeout(5000);
  });

  describe('get a billboard-200 chart for 2019-10-01', () => {
    it('should callback with the billboard-200 chart for this week', (done) => {
      getChart('billboard-200', '2019-10-01', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 200, 'chart has 200 songs');

        // test with missing image (should create a fixture for these tests)
        assert.deepEqual(chart.songs[11], {
          rank: 12,
          title: 'Quality Control: Control The Streets, Volume 2',
          artist: 'Various Artists',
          cover:
           'https://www.billboard.com/assets/1582845518/images/charts/bb-placeholder-new.jpg',
          position: { positionLastWeek: 13, peakPosition: 3, weeksOnChart: 6 },
        }, 'no images sizes song is correct');

        // testing alternate version of getting cover art
        assert.deepEqual(chart.songs[59], {
          rank: 60,
          title: 'Chronicle The 20 Greatest Hits',
          artist: 'Creedence Clearwater Revival',
          cover:
           'https://charts-static.billboard.com/img/1993/01/creedence-clearwater-revival-6ft-chronicle-the-20-greatest-hits-ttg.jpg',
          position: { positionLastWeek: 61, peakPosition: 22, weeksOnChart: 438 },
        }, 'alternate image size song is correct');

        done();
      });
    }).timeout(5000);
  });
});

describe('listCharts()', () => {
  describe('get all charts', () => {
    it('should callback with all available charts', (done) => {
      listCharts((err, charts) => {
        if (err) done(err);

        assert(charts, 'charts is non-null');
        assert(charts.length, 'charts is non-empty');

        for (let i = 0; i < charts.length; i += 1) {
          assert(charts[i], 'chart element is non-null and defined');
          assert(charts[i].name, 'chart element has name');
          assert(charts[i].url, 'chart element has url');
          assert(charts[i].url.split('http://www.billboard.com/charts/')[1], 'chart has correct format');
        }

        done();
      });
    }).timeout(5000);
  });
});
<commit_msg>increased test timeout<commit_after>const { assert } = require('chai');

const { getChart } = require('../billboard-top-100.js');
const { listCharts } = require('../billboard-top-100.js');

describe('getChart()', () => {
  describe('get a past chart (hot-100: week of 2016-11-19)', () => {
    it('should callback with the hot-100 chart for the week of 2016-11-19', (done) => {
      getChart('hot-100', '2016-11-19', (err, chart) => {
        if (err) done(err);

        assert.equal(chart.week, '2016-11-19', 'chart week is `2016-11-19`');
        assert.equal(chart.previousWeek.date, '2016-11-12', 'date of chart\'s previous week is `2016-11-12`');
        assert.equal(chart.previousWeek.url, 'http://www.billboard.com/charts/hot-100/2016-11-12', 'url of chart\'s previous week is correct');
        assert.equal(chart.nextWeek.date, '2016-11-26', 'date of chart\'s next week is `2016-11-26`');
        assert.equal(chart.nextWeek.url, 'http://www.billboard.com/charts/hot-100/2016-11-26', 'url of chart\'s next week is correct');

        assert.lengthOf(chart.songs, 100, 'chart has 100 songs');

        assert.deepEqual(chart.songs[0], {
          rank: 1,
          title: 'Closer',
          artist: 'The Chainsmokers Featuring Halsey',
          cover: 'https://charts-static.billboard.com/img/2016/08/the-chainsmokers-9iv.jpg',
          position: { positionLastWeek: 1, peakPosition: 1, weeksOnChart: 14 },
        }, 'first song is correct');

        assert.deepEqual(chart.songs[37], {
          rank: 38,
          title: 'Tiimmy Turner',
          artist: 'Desiigner',
          cover:
           'https://charts-static.billboard.com/img/2016/08/desiigner-l9j.jpg',
          position: { positionLastWeek: 37, peakPosition: 34, weeksOnChart: 15 },
        }, 'arbitrary (38th) song is correct');

        assert.deepEqual(chart.songs[99], {
          rank: 100,
          title: 'Cool Girl',
          artist: 'Tove Lo',
          cover: 'https://charts-static.billboard.com/img/2016/08/tove-lo-vxl.jpg',
          position: { positionLastWeek: NaN, peakPosition: 84, weeksOnChart: 5 },
        }, 'last song is correct');

        done();
      });
    }).timeout(10000);
  });

  describe('get a current chart (hot-100)', () => {
    it('should callback with the hot-100 chart for this week', (done) => {
      getChart('hot-100', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 100, 'chart has 100 songs');

        const firstSong = chart.songs[0];
        assert(firstSong, 'first song is non-null and defined');
        assert(firstSong.rank, 'first song has rank');
        assert(firstSong.title, 'first song has title');
        assert(firstSong.artist, 'first song has artist');
        assert(firstSong.position, 'first song has non-null and defined position');
        assert(firstSong.position.peakPosition, 'first song has peak position');
        assert(firstSong.position.weeksOnChart, 'first song has weeks on chart');

        const arbitrarySong = chart.songs[38];
        assert(arbitrarySong, 'arbitrary (38th) song is non-null and defined');
        assert(arbitrarySong.rank, 'arbitrary (38th) song has rank');
        assert(arbitrarySong.title, 'arbitrary (38th) song has title');
        assert(arbitrarySong.artist, 'arbitrary (38th) song has artist');
        assert(arbitrarySong.cover, 'arbitrary (38th) song has cover');
        assert(arbitrarySong.position, 'arbitrary (38th) song has non-null and defined position');
        assert(arbitrarySong.position.peakPosition, 'arbitrary (38th) song has peak position');
        assert(arbitrarySong.position.weeksOnChart, 'arbitrary (38th) song has weeks on chart');

        const lastSong = chart.songs[99];
        assert(lastSong, 'last song is non-null and defined');
        assert(lastSong.rank, 'last song has rank');
        assert(lastSong.title, 'last song has title');
        assert(lastSong.artist, 'last song has artist');
        assert(lastSong.cover, 'last song has cover');
        assert(lastSong.position, 'last song has non-null and defined position');
        assert(lastSong.position.peakPosition, 'last song has peak position');
        assert(lastSong.position.weeksOnChart, 'last song has weeks on chart');

        done();
      });
    }).timeout(10000);
  });

  describe('get a current chart (latin-songs)', () => {
    it('should callback with the latin-songs chart for this week', (done) => {
      getChart('latin-songs', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 50, 'chart has 50 songs');

        const firstSong = chart.songs[0];
        assert(firstSong, 'first song is non-null and defined');
        assert(firstSong.rank, 'first song has rank');
        assert(firstSong.title, 'first song has title');
        assert(firstSong.artist, 'first song has artist');
        assert(firstSong.position, 'first song has non-null and defined position');
        assert(firstSong.position.peakPosition, 'first song has peak position');
        assert(firstSong.position.weeksOnChart, 'first song has weeks on chart');

        const arbitrarySong = chart.songs[38];
        assert(arbitrarySong, 'arbitrary (38th) song is non-null and defined');
        assert(arbitrarySong.rank, 'arbitrary (38th) song has rank');
        assert(arbitrarySong.title, 'arbitrary (38th) song has title');
        assert(arbitrarySong.artist, 'arbitrary (38th) song has artist');
        assert(arbitrarySong.cover, 'arbitrary (38th) song has cover');
        assert(arbitrarySong.position, 'arbitrary (38th) song has non-null and defined position');
        assert(arbitrarySong.position.peakPosition, 'arbitrary (38th) song has peak position');
        assert(arbitrarySong.position.weeksOnChart, 'arbitrary (38th) song has weeks on chart');

        const lastSong = chart.songs[49];
        assert(lastSong, 'last song is non-null and defined');
        assert(lastSong.rank, 'last song has rank');
        assert(lastSong.title, 'last song has title');
        assert(lastSong.artist, 'last song has artist');
        assert(lastSong.cover, 'last song has cover');
        assert(lastSong.position, 'last song has non-null and defined position');
        assert(lastSong.position.peakPosition, 'last song has peak position');
        assert(lastSong.position.weeksOnChart, 'last song has weeks on chart');

        done();
      });
    }).timeout(10000);
  });

  describe('get a billboard-200 chart for 2019-10-01', () => {
    it('should callback with the billboard-200 chart for this week', (done) => {
      getChart('billboard-200', '2019-10-01', (err, chart) => {
        if (err) done(err);

        assert.lengthOf(chart.songs, 200, 'chart has 200 songs');

        // test with missing image (should create a fixture for these tests)
        assert.deepEqual(chart.songs[11], {
          rank: 12,
          title: 'Quality Control: Control The Streets, Volume 2',
          artist: 'Various Artists',
          cover:
           'https://www.billboard.com/assets/1582845518/images/charts/bb-placeholder-new.jpg',
          position: { positionLastWeek: 13, peakPosition: 3, weeksOnChart: 6 },
        }, 'no images sizes song is correct');

        // testing alternate version of getting cover art
        assert.deepEqual(chart.songs[59], {
          rank: 60,
          title: 'Chronicle The 20 Greatest Hits',
          artist: 'Creedence Clearwater Revival',
          cover:
           'https://charts-static.billboard.com/img/1993/01/creedence-clearwater-revival-6ft-chronicle-the-20-greatest-hits-ttg.jpg',
          position: { positionLastWeek: 61, peakPosition: 22, weeksOnChart: 438 },
        }, 'alternate image size song is correct');

        done();
      });
    }).timeout(10000);
  });
});

describe('listCharts()', () => {
  describe('get all charts', () => {
    it('should callback with all available charts', (done) => {
      listCharts((err, charts) => {
        if (err) done(err);

        assert(charts, 'charts is non-null');
        assert(charts.length, 'charts is non-empty');

        for (let i = 0; i < charts.length; i += 1) {
          assert(charts[i], 'chart element is non-null and defined');
          assert(charts[i].name, 'chart element has name');
          assert(charts[i].url, 'chart element has url');
          assert(charts[i].url.split('http://www.billboard.com/charts/')[1], 'chart has correct format');
        }

        done();
      });
    }).timeout(10000);
  });
});
<|endoftext|>


<commit_before>while_becomes_for: {
    options = { loops: true };
    input: {
        while (foo()) bar();
    }
    expect: {
        for (; foo(); ) bar();
    }
}

drop_if_break_1: {
    options = { loops: true };
    input: {
        for (;;)
            if (foo()) break;
    }
    expect: {
        for (; !foo(););
    }
}

drop_if_break_2: {
    options = { loops: true };
    input: {
        for (;bar();)
            if (foo()) break;
    }
    expect: {
        for (; bar() && !foo(););
    }
}

drop_if_break_3: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) break;
            stuff1();
            stuff2();
        }
    }
    expect: {
        for (; bar() && !foo();) {
            stuff1();
            stuff2();
        }
    }
}

drop_if_break_4: {
    options = { loops: true, sequences: true };
    input: {
        for (;bar();) {
            x();
            y();
            if (foo()) break;
            z();
            k();
        }
    }
    expect: {
        for (; bar() && (x(), y(), !foo());) z(), k();
    }
}

drop_if_else_break_1: {
    options = { loops: true };
    input: {
        for (;;) if (foo()) bar(); else break;
    }
    expect: {
        for (; foo(); ) bar();
    }
}

drop_if_else_break_2: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) baz();
            else break;
        }
    }
    expect: {
        for (; bar() && foo();) baz();
    }
}

drop_if_else_break_3: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) baz();
            else break;
            stuff1();
            stuff2();
        }
    }
    expect: {
        for (; bar() && foo();) {
            baz();
            stuff1();
            stuff2();
        }
    }
}

drop_if_else_break_4: {
    options = { loops: true, sequences: true };
    input: {
        for (;bar();) {
            x();
            y();
            if (foo()) baz();
            else break;
            z();
            k();
        }
    }
    expect: {
        for (; bar() && (x(), y(), foo());) baz(), z(), k();
    }
}

parse_do_while_with_semicolon: {
    input: {
        do {
            x();
        } while (false);y()
    }
    expect: {
        do x(); while (false);y();
    }
}

parse_do_while_without_semicolon: {
    input: {
        do {
            x();
        } while (false)y()
    }
    expect: {
        do x(); while (false);y();
    }
}<commit_msg>Disable loop optimization for parse-only tests<commit_after>while_becomes_for: {
    options = { loops: true };
    input: {
        while (foo()) bar();
    }
    expect: {
        for (; foo(); ) bar();
    }
}

drop_if_break_1: {
    options = { loops: true };
    input: {
        for (;;)
            if (foo()) break;
    }
    expect: {
        for (; !foo(););
    }
}

drop_if_break_2: {
    options = { loops: true };
    input: {
        for (;bar();)
            if (foo()) break;
    }
    expect: {
        for (; bar() && !foo(););
    }
}

drop_if_break_3: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) break;
            stuff1();
            stuff2();
        }
    }
    expect: {
        for (; bar() && !foo();) {
            stuff1();
            stuff2();
        }
    }
}

drop_if_break_4: {
    options = { loops: true, sequences: true };
    input: {
        for (;bar();) {
            x();
            y();
            if (foo()) break;
            z();
            k();
        }
    }
    expect: {
        for (; bar() && (x(), y(), !foo());) z(), k();
    }
}

drop_if_else_break_1: {
    options = { loops: true };
    input: {
        for (;;) if (foo()) bar(); else break;
    }
    expect: {
        for (; foo(); ) bar();
    }
}

drop_if_else_break_2: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) baz();
            else break;
        }
    }
    expect: {
        for (; bar() && foo();) baz();
    }
}

drop_if_else_break_3: {
    options = { loops: true };
    input: {
        for (;bar();) {
            if (foo()) baz();
            else break;
            stuff1();
            stuff2();
        }
    }
    expect: {
        for (; bar() && foo();) {
            baz();
            stuff1();
            stuff2();
        }
    }
}

drop_if_else_break_4: {
    options = { loops: true, sequences: true };
    input: {
        for (;bar();) {
            x();
            y();
            if (foo()) baz();
            else break;
            z();
            k();
        }
    }
    expect: {
        for (; bar() && (x(), y(), foo());) baz(), z(), k();
    }
}

parse_do_while_with_semicolon: {
    options = { loops: false };
    input: {
        do {
            x();
        } while (false);y()
    }
    expect: {
        do x(); while (false);y();
    }
}

parse_do_while_without_semicolon: {
    options = { loops: false };
    input: {
        do {
            x();
        } while (false)y()
    }
    expect: {
        do x(); while (false);y();
    }
}<|endoftext|>