<commit_before>require(`v8-compile-cache`)

const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const FriendlyErrorsWebpackPlugin = require(`friendly-errors-webpack-plugin`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const debug = require(`debug`)(`gatsby:webpack-config`)
const report = require(`gatsby-cli/lib/reporter`)
const { withBasePath } = require(`./path`)

const apiRunnerNode = require(`./api-runner-node`)
const createUtils = require(`./webpack-utils`)
const hasLocalEslint = require(`./local-eslint-config-finder`)

// Four stages or modes:
//   1) develop: for `gatsby develop` command, hot reload and CSS injection into page
//   2) develop-html: same as develop without react-hmre in the babel config for html renderer
//   3) build-javascript: Build JS and CSS chunks for production
//   4) build-html: build all HTML files

module.exports = async (
  program,
  directory,
  suppliedStage,
  webpackPort = 1500
) => {
  const directoryPath = withBasePath(directory)

  process.env.GATSBY_BUILD_STAGE = suppliedStage

  // We combine develop & develop-html stages for purposes of generating the
  // webpack config.
  const stage = suppliedStage
  const { rules, loaders, plugins } = await createUtils({ stage, program })

  function processEnv(stage, defaultNodeEnv) {
    debug(`Building env for "${stage}"`)
    const env = process.env.NODE_ENV
      ? process.env.NODE_ENV
      : `${defaultNodeEnv}`
    const envFile = path.join(process.cwd(), `./.env.${env}`)
    let parsed = {}
    try {
      parsed = dotenv.parse(fs.readFileSync(envFile, { encoding: `utf8` }))
    } catch (err) {
      if (err.code !== `ENOENT`) {
        report.error(`There was a problem processing the .env file`, err)
      }
    }

    const envObject = Object.keys(parsed).reduce((acc, key) => {
      acc[key] = JSON.stringify(parsed[key])
      return acc
    }, {})

    const gatsbyVarObject = Object.keys(process.env).reduce((acc, key) => {
      if (key.match(/^GATSBY_/)) {
        acc[key] = JSON.stringify(process.env[key])
      }
      return acc
    }, {})

    // Don't allow overwriting of NODE_ENV, PUBLIC_DIR as to not break gatsby things
    envObject.NODE_ENV = JSON.stringify(env)
    envObject.PUBLIC_DIR = JSON.stringify(`${process.cwd()}/public`)
    envObject.BUILD_STAGE = JSON.stringify(stage)

    return Object.assign(envObject, gatsbyVarObject)
  }

  function getHmrPath() {
    let hmrBasePath = `${program.ssl ? `https` : `http`}://${
      program.host
    }:${webpackPort}/`

    const hmrSuffix = `__webpack_hmr&reload=true&overlay=false`

    if (process.env.GATSBY_WEBPACK_PUBLICPATH) {
      const pubPath = process.env.GATSBY_WEBPACK_PUBLICPATH
      if (pubPath.substr(-1) === `/`) {
        hmrBasePath = pubPath
      } else {
        hmrBasePath = `${pubPath}/`
      }
    }

    return hmrBasePath + hmrSuffix
  }

  debug(`Loading webpack config for stage "${stage}"`)
  function getOutput() {
    switch (stage) {
      case `develop`:
        return {
          path: directory,
          filename: `[name].js`,
          // Add /* filename */ comments to generated require()s in the output.
          pathinfo: true,
          // Point sourcemap entries to original disk location (format as URL on Windows)
          publicPath:
            process.env.GATSBY_WEBPACK_PUBLICPATH ||
            `${program.ssl ? `https` : `http`}://${
              program.host
            }:${webpackPort}/`,
          devtoolModuleFilenameTemplate: info =>
            path.resolve(info.absoluteResourcePath).replace(/\\/g, `/`),
          // Avoid React cross-origin errors
          // See https://reactjs.org/docs/cross-origin-errors.html
          crossOriginLoading: `anonymous`,
        }
      case `build-html`:
      case `develop-html`:
        // A temp file required by static-site-generator-plugin. See plugins() below.
        // Deleted by build-html.js, since it's not needed for production.
        return {
          path: directoryPath(`public`),
          filename: `render-page.js`,
          libraryTarget: `umd`,
          library: `lib`,
          umdNamedDefine: true,
          globalObject: `this`,
          publicPath: program.prefixPaths
            ? `${store.getState().config.pathPrefix}/`
            : `/`,
        }
      case `build-javascript`:
        return {
          filename: `[name]-[contenthash].js`,
          chunkFilename: `[name]-[contenthash].js`,
          path: directoryPath(`public`),
          publicPath: program.prefixPaths
            ? `${store.getState().config.pathPrefix}/`
            : `/`,
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getEntry() {
    switch (stage) {
      case `develop`:
        return {
          commons: [
            require.resolve(`react-hot-loader/patch`),
            `${require.resolve(
              `webpack-hot-middleware/client`
            )}?path=${getHmrPath()}`,
            directoryPath(`.cache/app`),
          ],
        }
      case `develop-html`:
        return {
          main: directoryPath(`.cache/develop-static-entry`),
        }
      case `build-html`:
        return {
          main: directoryPath(`.cache/static-entry`),
        }
      case `build-javascript`:
        return {
          app: directoryPath(`.cache/production-app`),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getPlugins() {
    let configPlugins = [
      plugins.moment(),

      // Add a few global variables. Set NODE_ENV to production (enables
      // optimizations for React) and what the link prefix is (__PATH_PREFIX__).
      plugins.define({
        "process.env": processEnv(stage, `development`),
        __PATH_PREFIX__: JSON.stringify(
          program.prefixPaths ? store.getState().config.pathPrefix : ``
        ),
      }),
    ]

    switch (stage) {
      case `develop`:
        configPlugins = configPlugins.concat([
          plugins.hotModuleReplacement(),
          plugins.noEmitOnErrors(),

          new FriendlyErrorsWebpackPlugin({
            clearConsole: false,
          }),
        ])
        break
      case `build-javascript`: {
        // Minify Javascript only if needed.
        configPlugins = program.noUglify
          ? configPlugins
          : configPlugins.concat([
              plugins.uglify({
                uglifyOptions: {
                  compress: {
                    drop_console: false,
                  },
                },
              }),
            ])
        configPlugins = configPlugins.concat([
          plugins.extractText(),
          // Write out stats object mapping named dynamic imports (aka page
          // components) to all their async chunks.
          {
            apply: function(compiler) {
              compiler.hooks.done.tapAsync(
                `gatsby-webpack-stats-extractor`,
                (stats, done) => {
                  let assets = {}
                  let assetsMap = {}
                  for (let chunkGroup of stats.compilation.chunkGroups) {
                    if (chunkGroup.name) {
                      let files = []
                      for (let chunk of chunkGroup.chunks) {
                        files.push(...chunk.files)
                      }
                      assets[chunkGroup.name] = files.filter(
                        f => f.slice(-4) !== `.map`
                      )
                      assetsMap[chunkGroup.name] =
                        `/` +
                        files.filter(
                          f =>
                            f.slice(-3) !== `.js` &&
                            f.slice(0, chunkGroup.name.length) ===
                              chunkGroup.name
                        )[0]
                    }
                  }

                  const webpackStats = {
                    ...stats.toJson({ all: false, chunkGroups: true }),
                    assetsByChunkName: assets,
                  }

                  fs.writeFile(
                    path.join(`public`, `chunk-map.json`),
                    JSON.stringify(assetsMap),
                    () => {
                      fs.writeFile(
                        path.join(`public`, `webpack.stats.json`),
                        JSON.stringify(webpackStats),
                        done
                      )
                    }
                  )
                }
              )
            },
          },
        ])
        break
      }
    }

    return configPlugins
  }

  function getDevtool() {
    switch (stage) {
      case `develop`:
        return `eval`
      // use a normal `source-map` for the html phases since
      // it gives better line and column numbers
      case `develop-html`:
      case `build-html`:
      case `build-javascript`:
        return `source-map`
      default:
        return false
    }
  }

  function getMode() {
    switch (stage) {
      case `build-javascript`:
        return `production`
      case `develop`:
      case `develop-html`:
      case `build-html`:
        return `development` // So we don't uglify the html bundle
      default:
        return `production`
    }
  }

  function getModule(config) {
    // Common config for every env.
    // prettier-ignore
    let configRules = [
      rules.js(),
      rules.yaml(),
      rules.fonts(),
      rules.images(),
      rules.media(),
      rules.miscAssets(),
    ]
    switch (stage) {
      case `develop`: {
        // get schema to pass to eslint config and program for directory
        const { schema, program } = store.getState()

        // if no local eslint config, then add gatsby config
        if (!hasLocalEslint(program.directory)) {
          configRules = configRules.concat([rules.eslint(schema)])
        }

        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
      }
      case `build-html`:
      case `develop-html`:
        // We don't deal with CSS at all when building the HTML.
        // The 'null' loader is used to prevent 'module not found' errors.
        // On the other hand CSS modules loaders are necessary.

        // prettier-ignore
        configRules = configRules.concat([
          {
            oneOf: [
              rules.cssModules(),
              {
                ...rules.css(),
                use: [loaders.null()],
              },
            ],
          },
        ])
        break

      case `build-javascript`:
        // We don't deal with CSS at all when building JavaScript but we still
        // need to process the CSS so offline-plugin knows about the various
        // assets referenced in your CSS.
        //
        // It's also necessary to process CSS Modules so your JS knows the
        // classNames to use.
        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
    }

    return { rules: configRules }
  }

  function getResolve() {
    const { program } = store.getState()
    return {
      // Use the program's extension list (generated via the
      // 'resolvableExtensions' API hook).
      extensions: [...program.extensions],
      // Default to using the site's node_modules directory to look for
      // modules. But also make it possible to install modules within the src
      // directory if you need to install a specific version of a module for a
      // part of your site.
      modules: [
        directoryPath(path.join(`node_modules`)),
        `node_modules`,
        // This is head scratching - without it css modules in production will fail
        // to find module with relative path
        `./`,
      ],
      alias: {
        gatsby$: directoryPath(path.join(`.cache`, `gatsby-browser-entry.js`)),
        // Using directories for module resolution is mandatory because
        // relative path imports are used sometimes
        // See https://stackoverflow.com/a/49455609/6420957 for more details
        "@babel/runtime": path.dirname(
          require.resolve(`@babel/runtime/package.json`)
        ),
        "core-js": path.dirname(require.resolve(`core-js/package.json`)),
        "react-hot-loader": path.dirname(
          require.resolve(`react-hot-loader/package.json`)
        ),
        "react-lifecycles-compat": directoryPath(
          `.cache/react-lifecycles-compat.js`
        ),
        "create-react-context": directoryPath(`.cache/create-react-context.js`),
      },
    }
  }

  function getResolveLoader() {
    const root = [path.resolve(directory, `node_modules`)]

    const userLoaderDirectoryPath = path.resolve(directory, `loaders`)

    try {
      if (fs.statSync(userLoaderDirectoryPath).isDirectory()) {
        root.push(userLoaderDirectoryPath)
      }
    } catch (err) {
      debug(`Error resolving user loaders directory`, err)
    }

    return {
      modules: [...root, path.join(__dirname, `../loaders`), `node_modules`],
    }
  }

  const config = {
    // Context is the base directory for resolving the entry option.
    context: directory,
    entry: getEntry(),
    output: getOutput(),

    module: getModule(),
    plugins: getPlugins(),

    // Certain "isomorphic" packages have different entry points for browser
    // and server (see
    // https://github.com/defunctzombie/package-browser-field-spec); setting
    // the target tells webpack which file to include, ie. browser vs main.
    target: stage === `build-html` || stage === `develop-html` ? `node` : `web`,
    profile: stage === `production`,
    devtool: getDevtool(),
    // Turn off performance hints as we (for now) don't want to show the normal
    // webpack output anywhere.
    performance: {
      hints: false,
    },
    mode: getMode(),

    resolveLoader: getResolveLoader(),
    resolve: getResolve(),

    node: {
      __filename: true,
    },
  }

  if (stage === `build-javascript`) {
    config.optimization = {
      runtimeChunk: {
        name: `webpack-runtime`,
      },
      splitChunks: {
        name: false,
      },
      minimize: !program.noUglify,
    }
  }

  if (stage === `build-html` || stage === `develop-html`) {
    const externalList = [
      // match `lodash` and `lodash/foo`
      // but not things like `lodash-es`
      `lodash`,
      /^lodash\//,
      `react`,
      /^react-dom\//,
      `pify`,
      `@reach/router`,
      `@reach/router/lib/history`,
      `common-tags`,
      `path`,
      `semver`,
      `react-helmet`,
      `minimatch`,
      `fs`,
      /^core-js\//,
      `es6-promise`,
      `crypto`,
      `zlib`,
      `http`,
      `https`,
      `debug`,
    ]

    config.externals = [
      function(context, request, callback) {
        if (
          externalList.some(item => {
            if (typeof item === `string` && item === request) {
              return true
            } else if (item instanceof RegExp && item.test(request)) {
              return true
            }

            return false
          })
        ) {
          return callback(null, `umd ${request}`)
        }
        return callback()
      },
    ]
  }

  store.dispatch(actions.replaceWebpackConfig(config))
  const getConfig = () => store.getState().webpack

  await apiRunnerNode(`onCreateWebpackConfig`, {
    getConfig,
    stage,
    rules,
    loaders,
    plugins,
  })

  return getConfig()
}
<commit_msg>Fix typo<commit_after>require(`v8-compile-cache`)

const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const FriendlyErrorsWebpackPlugin = require(`friendly-errors-webpack-plugin`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const debug = require(`debug`)(`gatsby:webpack-config`)
const report = require(`gatsby-cli/lib/reporter`)
const { withBasePath } = require(`./path`)

const apiRunnerNode = require(`./api-runner-node`)
const createUtils = require(`./webpack-utils`)
const hasLocalEslint = require(`./local-eslint-config-finder`)

// Four stages or modes:
//   1) develop: for `gatsby develop` command, hot reload and CSS injection into page
//   2) develop-html: same as develop without react-hmre in the babel config for html renderer
//   3) build-javascript: Build JS and CSS chunks for production
//   4) build-html: build all HTML files

module.exports = async (
  program,
  directory,
  suppliedStage,
  webpackPort = 1500
) => {
  const directoryPath = withBasePath(directory)

  process.env.GATSBY_BUILD_STAGE = suppliedStage

  // We combine develop & develop-html stages for purposes of generating the
  // webpack config.
  const stage = suppliedStage
  const { rules, loaders, plugins } = await createUtils({ stage, program })

  function processEnv(stage, defaultNodeEnv) {
    debug(`Building env for "${stage}"`)
    const env = process.env.NODE_ENV
      ? process.env.NODE_ENV
      : `${defaultNodeEnv}`
    const envFile = path.join(process.cwd(), `./.env.${env}`)
    let parsed = {}
    try {
      parsed = dotenv.parse(fs.readFileSync(envFile, { encoding: `utf8` }))
    } catch (err) {
      if (err.code !== `ENOENT`) {
        report.error(`There was a problem processing the .env file`, err)
      }
    }

    const envObject = Object.keys(parsed).reduce((acc, key) => {
      acc[key] = JSON.stringify(parsed[key])
      return acc
    }, {})

    const gatsbyVarObject = Object.keys(process.env).reduce((acc, key) => {
      if (key.match(/^GATSBY_/)) {
        acc[key] = JSON.stringify(process.env[key])
      }
      return acc
    }, {})

    // Don't allow overwriting of NODE_ENV, PUBLIC_DIR as to not break gatsby things
    envObject.NODE_ENV = JSON.stringify(env)
    envObject.PUBLIC_DIR = JSON.stringify(`${process.cwd()}/public`)
    envObject.BUILD_STAGE = JSON.stringify(stage)

    return Object.assign(envObject, gatsbyVarObject)
  }

  function getHmrPath() {
    let hmrBasePath = `${program.ssl ? `https` : `http`}://${
      program.host
    }:${webpackPort}/`

    const hmrSuffix = `__webpack_hmr&reload=true&overlay=false`

    if (process.env.GATSBY_WEBPACK_PUBLICPATH) {
      const pubPath = process.env.GATSBY_WEBPACK_PUBLICPATH
      if (pubPath.substr(-1) === `/`) {
        hmrBasePath = pubPath
      } else {
        hmrBasePath = `${pubPath}/`
      }
    }

    return hmrBasePath + hmrSuffix
  }

  debug(`Loading webpack config for stage "${stage}"`)
  function getOutput() {
    switch (stage) {
      case `develop`:
        return {
          path: directory,
          filename: `[name].js`,
          // Add /* filename */ comments to generated require()s in the output.
          pathinfo: true,
          // Point sourcemap entries to original disk location (format as URL on Windows)
          publicPath:
            process.env.GATSBY_WEBPACK_PUBLICPATH ||
            `${program.ssl ? `https` : `http`}://${
              program.host
            }:${webpackPort}/`,
          devtoolModuleFilenameTemplate: info =>
            path.resolve(info.absoluteResourcePath).replace(/\\/g, `/`),
          // Avoid React cross-origin errors
          // See https://reactjs.org/docs/cross-origin-errors.html
          crossOriginLoading: `anonymous`,
        }
      case `build-html`:
      case `develop-html`:
        // A temp file required by static-site-generator-plugin. See plugins() below.
        // Deleted by build-html.js, since it's not needed for production.
        return {
          path: directoryPath(`public`),
          filename: `render-page.js`,
          libraryTarget: `umd`,
          library: `lib`,
          umdNamedDefine: true,
          globalObject: `this`,
          publicPath: program.prefixPaths
            ? `${store.getState().config.pathPrefix}/`
            : `/`,
        }
      case `build-javascript`:
        return {
          filename: `[name]-[contenthash].js`,
          chunkFilename: `[name]-[contenthash].js`,
          path: directoryPath(`public`),
          publicPath: program.prefixPaths
            ? `${store.getState().config.pathPrefix}/`
            : `/`,
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getEntry() {
    switch (stage) {
      case `develop`:
        return {
          commons: [
            require.resolve(`react-hot-loader/patch`),
            `${require.resolve(
              `webpack-hot-middleware/client`
            )}?path=${getHmrPath()}`,
            directoryPath(`.cache/app`),
          ],
        }
      case `develop-html`:
        return {
          main: directoryPath(`.cache/develop-static-entry`),
        }
      case `build-html`:
        return {
          main: directoryPath(`.cache/static-entry`),
        }
      case `build-javascript`:
        return {
          app: directoryPath(`.cache/production-app`),
        }
      default:
        throw new Error(`The state requested ${stage} doesn't exist.`)
    }
  }

  function getPlugins() {
    let configPlugins = [
      plugins.moment(),

      // Add a few global variables. Set NODE_ENV to production (enables
      // optimizations for React) and what the link prefix is (__PATH_PREFIX__).
      plugins.define({
        "process.env": processEnv(stage, `development`),
        __PATH_PREFIX__: JSON.stringify(
          program.prefixPaths ? store.getState().config.pathPrefix : ``
        ),
      }),
    ]

    switch (stage) {
      case `develop`:
        configPlugins = configPlugins.concat([
          plugins.hotModuleReplacement(),
          plugins.noEmitOnErrors(),

          new FriendlyErrorsWebpackPlugin({
            clearConsole: false,
          }),
        ])
        break
      case `build-javascript`: {
        // Minify Javascript only if needed.
        configPlugins = program.noUglify
          ? configPlugins
          : configPlugins.concat([
              plugins.uglify({
                uglifyOptions: {
                  compress: {
                    drop_console: false,
                  },
                },
              }),
            ])
        configPlugins = configPlugins.concat([
          plugins.extractText(),
          // Write out stats object mapping named dynamic imports (aka page
          // components) to all their async chunks.
          {
            apply: function(compiler) {
              compiler.hooks.done.tapAsync(
                `gatsby-webpack-stats-extractor`,
                (stats, done) => {
                  let assets = {}
                  let assetsMap = {}
                  for (let chunkGroup of stats.compilation.chunkGroups) {
                    if (chunkGroup.name) {
                      let files = []
                      for (let chunk of chunkGroup.chunks) {
                        files.push(...chunk.files)
                      }
                      assets[chunkGroup.name] = files.filter(
                        f => f.slice(-4) !== `.map`
                      )
                      assetsMap[chunkGroup.name] =
                        `/` +
                        files.filter(
                          f =>
                            f.slice(-3) === `.js` &&
                            f.slice(0, chunkGroup.name.length) ===
                              chunkGroup.name
                        )[0]
                    }
                  }

                  const webpackStats = {
                    ...stats.toJson({ all: false, chunkGroups: true }),
                    assetsByChunkName: assets,
                  }

                  fs.writeFile(
                    path.join(`public`, `chunk-map.json`),
                    JSON.stringify(assetsMap),
                    () => {
                      fs.writeFile(
                        path.join(`public`, `webpack.stats.json`),
                        JSON.stringify(webpackStats),
                        done
                      )
                    }
                  )
                }
              )
            },
          },
        ])
        break
      }
    }

    return configPlugins
  }

  function getDevtool() {
    switch (stage) {
      case `develop`:
        return `eval`
      // use a normal `source-map` for the html phases since
      // it gives better line and column numbers
      case `develop-html`:
      case `build-html`:
      case `build-javascript`:
        return `source-map`
      default:
        return false
    }
  }

  function getMode() {
    switch (stage) {
      case `build-javascript`:
        return `production`
      case `develop`:
      case `develop-html`:
      case `build-html`:
        return `development` // So we don't uglify the html bundle
      default:
        return `production`
    }
  }

  function getModule(config) {
    // Common config for every env.
    // prettier-ignore
    let configRules = [
      rules.js(),
      rules.yaml(),
      rules.fonts(),
      rules.images(),
      rules.media(),
      rules.miscAssets(),
    ]
    switch (stage) {
      case `develop`: {
        // get schema to pass to eslint config and program for directory
        const { schema, program } = store.getState()

        // if no local eslint config, then add gatsby config
        if (!hasLocalEslint(program.directory)) {
          configRules = configRules.concat([rules.eslint(schema)])
        }

        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
      }
      case `build-html`:
      case `develop-html`:
        // We don't deal with CSS at all when building the HTML.
        // The 'null' loader is used to prevent 'module not found' errors.
        // On the other hand CSS modules loaders are necessary.

        // prettier-ignore
        configRules = configRules.concat([
          {
            oneOf: [
              rules.cssModules(),
              {
                ...rules.css(),
                use: [loaders.null()],
              },
            ],
          },
        ])
        break

      case `build-javascript`:
        // We don't deal with CSS at all when building JavaScript but we still
        // need to process the CSS so offline-plugin knows about the various
        // assets referenced in your CSS.
        //
        // It's also necessary to process CSS Modules so your JS knows the
        // classNames to use.
        configRules = configRules.concat([
          {
            oneOf: [rules.cssModules(), rules.css()],
          },
        ])

        break
    }

    return { rules: configRules }
  }

  function getResolve() {
    const { program } = store.getState()
    return {
      // Use the program's extension list (generated via the
      // 'resolvableExtensions' API hook).
      extensions: [...program.extensions],
      // Default to using the site's node_modules directory to look for
      // modules. But also make it possible to install modules within the src
      // directory if you need to install a specific version of a module for a
      // part of your site.
      modules: [
        directoryPath(path.join(`node_modules`)),
        `node_modules`,
        // This is head scratching - without it css modules in production will fail
        // to find module with relative path
        `./`,
      ],
      alias: {
        gatsby$: directoryPath(path.join(`.cache`, `gatsby-browser-entry.js`)),
        // Using directories for module resolution is mandatory because
        // relative path imports are used sometimes
        // See https://stackoverflow.com/a/49455609/6420957 for more details
        "@babel/runtime": path.dirname(
          require.resolve(`@babel/runtime/package.json`)
        ),
        "core-js": path.dirname(require.resolve(`core-js/package.json`)),
        "react-hot-loader": path.dirname(
          require.resolve(`react-hot-loader/package.json`)
        ),
        "react-lifecycles-compat": directoryPath(
          `.cache/react-lifecycles-compat.js`
        ),
        "create-react-context": directoryPath(`.cache/create-react-context.js`),
      },
    }
  }

  function getResolveLoader() {
    const root = [path.resolve(directory, `node_modules`)]

    const userLoaderDirectoryPath = path.resolve(directory, `loaders`)

    try {
      if (fs.statSync(userLoaderDirectoryPath).isDirectory()) {
        root.push(userLoaderDirectoryPath)
      }
    } catch (err) {
      debug(`Error resolving user loaders directory`, err)
    }

    return {
      modules: [...root, path.join(__dirname, `../loaders`), `node_modules`],
    }
  }

  const config = {
    // Context is the base directory for resolving the entry option.
    context: directory,
    entry: getEntry(),
    output: getOutput(),

    module: getModule(),
    plugins: getPlugins(),

    // Certain "isomorphic" packages have different entry points for browser
    // and server (see
    // https://github.com/defunctzombie/package-browser-field-spec); setting
    // the target tells webpack which file to include, ie. browser vs main.
    target: stage === `build-html` || stage === `develop-html` ? `node` : `web`,
    profile: stage === `production`,
    devtool: getDevtool(),
    // Turn off performance hints as we (for now) don't want to show the normal
    // webpack output anywhere.
    performance: {
      hints: false,
    },
    mode: getMode(),

    resolveLoader: getResolveLoader(),
    resolve: getResolve(),

    node: {
      __filename: true,
    },
  }

  if (stage === `build-javascript`) {
    config.optimization = {
      runtimeChunk: {
        name: `webpack-runtime`,
      },
      splitChunks: {
        name: false,
      },
      minimize: !program.noUglify,
    }
  }

  if (stage === `build-html` || stage === `develop-html`) {
    const externalList = [
      // match `lodash` and `lodash/foo`
      // but not things like `lodash-es`
      `lodash`,
      /^lodash\//,
      `react`,
      /^react-dom\//,
      `pify`,
      `@reach/router`,
      `@reach/router/lib/history`,
      `common-tags`,
      `path`,
      `semver`,
      `react-helmet`,
      `minimatch`,
      `fs`,
      /^core-js\//,
      `es6-promise`,
      `crypto`,
      `zlib`,
      `http`,
      `https`,
      `debug`,
    ]

    config.externals = [
      function(context, request, callback) {
        if (
          externalList.some(item => {
            if (typeof item === `string` && item === request) {
              return true
            } else if (item instanceof RegExp && item.test(request)) {
              return true
            }

            return false
          })
        ) {
          return callback(null, `umd ${request}`)
        }
        return callback()
      },
    ]
  }

  store.dispatch(actions.replaceWebpackConfig(config))
  const getConfig = () => store.getState().webpack

  await apiRunnerNode(`onCreateWebpackConfig`, {
    getConfig,
    stage,
    rules,
    loaders,
    plugins,
  })

  return getConfig()
}
<|endoftext|>


<commit_before>'use strict';

var db = require('mano').db,
	user = db.User.prototype;

exports['step-documents'] = { class: { 'step-active': true } };

exports.step = function () {
	div(
		{ class: 'capital-first' },
		div("3"),
		div(h1("Upload Your Documents"),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit."))
	);

	div(
		{ class: 'disabler-range', id: 'documents-disabler-range' },
		section(
			ul(
				{ class: 'sections-primary-list user-documents-upload' },
				user.requiredSubmissions,
				function (submission) {
					return li({ class: 'section-primary' },
						form(
							div(
								h2(submission.label),
								small(submission.legend),
								hr(),
								input({ dbjs: submission._files })
							)
						)
						);
				}
			)
		),

		div({ class: 'user-next-step-button' },
			a({ href: '/submission/' }, "Continue to next step")
			),
		div({ class: 'disabler' })
	);
};
<commit_msg>Assure SPA look<commit_after>'use strict';

var db = require('mano').db,
	user = db.User.prototype;

exports['step-documents'] = { class: { 'step-active': true } };

exports.step = function () {
	div(
		{ class: 'capital-first' },
		div("3"),
		div(h1("Upload Your Documents"),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit."))
	);

	div(
		{ class: 'disabler-range', id: 'documents-disabler-range' },
		section(
			ul(
				{ class: 'sections-primary-list user-documents-upload' },
				user.requiredSubmissions,
				function (submission) {
					return li({ class: 'section-primary' },
						form({ class: 'auto-submit' },
							div(
								h2(submission.label),
								small(submission.legend),
								hr(),
								input({ dbjs: submission._files })
							)
						)
						);
				}
			)
		),

		div({ class: 'user-next-step-button' },
			a({ href: '/submission/' }, "Continue to next step")
			),
		div({ class: 'disabler' })
	);
};
<|endoftext|>


<commit_before>// @flow
/**
 * Part of GDL gdl-frontend.
 * Copyright (C) 2017 GDL
 *
 * See LICENSE
 */

/**
 * Colors we use in GDL
 * purple: #B4A4E5
 * blue: #5BCDE5
 * green: #90CE4C
 * yellow: #F1C528
 * orange: #FF9442
 * light red: #EE6D6D
 * pink: #EE8BD0
 */
const colorMap = {
  Level1: '#75C1FD',
  Level2: '#5DDAC8',
  Level3: '#97CE4C',
  Level4: '#F1C528',
  Level5: '#FF9442',
  Level6: '#FD6E68',
  ReadAloud: '#F898D0',
  Decodable: '#BFA2E9',
  Games: '#BBBEC1'
};

export default colorMap;
<commit_msg>fix: flow typ fixes<commit_after>// @flow
/**
 * Part of GDL gdl-frontend.
 * Copyright (C) 2017 GDL
 *
 * See LICENSE
 */
import type { ReadingLevel } from '../gqlTypes';
/**
 * Colors we use in GDL
 * purple: #B4A4E5
 * blue: #5BCDE5
 * green: #90CE4C
 * yellow: #F1C528
 * orange: #FF9442
 * light red: #EE6D6D
 * pink: #EE8BD0
 */

const colorMap: { [key: ReadingLevel | 'Games']: string } = {
  Level1: '#75C1FD',
  Level2: '#5DDAC8',
  Level3: '#97CE4C',
  Level4: '#F1C528',
  Level5: '#FF9442',
  Level6: '#FD6E68',
  ReadAloud: '#F898D0',
  Decodable: '#BFA2E9',
  Games: '#BBBEC1'
};

export default colorMap;
<|endoftext|>


<commit_before>(function() {

  // There will be only 1 Pappu

  mit.Pappu = {
    x: 50,
    y: 10,
    w: 50,
    h: 50,

    invincible: 0,
    invincibility_start: 0,
    invincibility_time: 0,
    clones: [],

    rotate_angle: 0,

    sprite: {},
    sound: '',

    // Rate of sprite frame change
    // per animation frame.
    change_per_frame: 10,

    fly_frame_count: 0,
    max_fly_frame_count: 10,

    init: function() {
      this.sound = document.getElementById("flap");

      // Initializing Pappu Sprite, lolzzz..!
      // this.sprite = new Image();
      // this.sprite.src = 'img/pappu.png';
      this.sprite = mit.image.pappu;

      //pappu.w = pappu.sprite.width;
      mit.Pappu.w = mit.Pappu.sprite.width;
      mit.Pappu.h = 60;

      // Sprite Frame Count
      mit.Pappu.max_fly_frame_count = 8;
      mit.Pappu.max_fly_frame_count--;

      // Sprite Frame Change Speed.
      // This will affect the flap speed.
      // 1.6 is the perfect value!
      mit.Pappu.change_per_frame = 1.6;

      // X Pos
      mit.Pappu.x = 33;
    },

    undoInvincible: function() {
      this.invincible = 0;
      this.invincibility_start = 0;
      this.invincible_timer = 0;

      mit.ui.invincible_timer.hide();
    },

    draw: function(ctx) {
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;

      if (utils.isInt(cur_sprite_frame)) {
        var source_y = cur_sprite_frame * 60;
      }

      else {
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;

        // Ultra smooth animations
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
        var source_y = old_sprite_frame * 60;
      }

      // console.log(cur_sprite_frame, source_x);

      // Rotation on Flying
      if (mit.flying_up) {
        this.sound.play();

        if (this.rotate_angle > -15) {
          this.rotate_angle -= 2;
        }

        ctx.save();

        ctx.translate(this.x, this.y);
        ctx.translate(this.w/2, this.h/2);
        ctx.rotate(utils.toRadian(this.rotate_angle));
      }
      else if (mit.game_over) {
        // draw() is called as long as
        // pappu hasnt hit boundaries and over'ed the game :P

        // Game Over Gugglu!
        this.rotate_angle += 2;

        ctx.save();

        ctx.translate(this.x, this.y);
        ctx.translate(this.w/2, this.h/2);
        ctx.rotate(utils.toRadian(this.rotate_angle));
      }
      else {
        if (this.rotate_angle < 30) {
          this.rotate_angle += 2;
        }

        ctx.save();

        ctx.translate(this.x, this.y);
        ctx.translate(this.w/2, this.h/2);
        ctx.rotate(utils.toRadian(this.rotate_angle));
      }

      if (this.invincible) {
        ctx.globalAlpha = 0.4;

        // Current time
        var cur_time = new Date().getTime();
        var time_diff = cur_time - this.invincibility_start;

        var timer_progress = (time_diff/this.invincibility_time) * 100;

        if (timer_progress > 100)
          this.undoInvincible();
        else
          mit.ui.invincible_loader.css('width', timer_progress + '%');

        // console.log(timer_progress)
      }

      ctx.drawImage(
          this.sprite,
          0,
          source_y,
          this.w,
          60,
          -this.w/2,
          -this.h/2,
          this.w,
          60
        );

      ctx.restore();
    },

    drawStatic: function(ctx) {
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;

      if (utils.isInt(cur_sprite_frame)) {
        var source_y = cur_sprite_frame * 60;
      }

      else {
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;

        // Ultra smooth animations
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
        var source_y = old_sprite_frame * 60;
      }

      this.y = mit.Backgrounds.log_y-42;

      /*ctx.drawImage(
        this.sprite,
        0,
        0,
        this.w,
        60,
        this.x,
        this.y,
        this.w,
        60
      );*/

      ctx.drawImage(
        this.sprite,
        0,
        source_y,
        this.w,
        60,
        this.x,
        this.y,
        this.w,
        60
      );
    },

    updateFlyFrameCount: function(count) {
      if (typeof count !== 'number') {
        this.fly_frame_count++;

        if (parseInt(this.fly_frame_count/this.change_per_frame) > this.max_fly_frame_count) {
          this.fly_frame_count = 0;
        }

        return;
      }

      this.fly_frame_count = count;
    },

    hasReachedBoundary: function(canvas_width, canvas_height) {
      // Crossed Sides ?
      // `c` stands for crossed

      var ctop = (this.y < 0 - this.h);
      var cbtm = (this.y > mit.H);
      var cleft = (this.x < 0);
      var crgt = (this.x > mit.W);

      // return true if crossed any sides
      if (ctop || cbtm || cleft || crgt) {
        return true;
      }

      return false;
    },

    getBounds: function() {
      var b = {};

      b.start_x = this.x;
      b.start_y = this.y;
      b.end_x   = this.x + this.w;
      b.end_y   = this.y + this.h;

      return b;
    },

    createClones: function(count) {
      // This method will be usually called
      // when pappu gathers a 'clone' collectible.

      var pappu_clone;

      for (var i = 0; i < count; i++) {
        pappu_clone = Object.create(mit.Pappu);

        this.clones.push(pappu_clone);
      }

      return;
    },

    drawClones: function(ctx) {

      var self = this;

      self.clones.forEach(function(clone, index) {
        if (clone.x > mit.W || clone.y < 0 || clone.y > mit.H)
          self.clones.splice(index, 1);

        clone.x += utils.randomNumber(5, 10);
        clone.y += utils.randomNumber(-20, 20);

        clone.draw(ctx);
      });

      return;
    },

    checkCloneCollision: function() {

      var self = this;

      // super optimization :P
      if (!self.clones.length)
        return;

      var branches = mit.BranchUtils.branches;
      var forks = mit.ForkUtils.forks;
      var pakias = mit.PakiaUtils.pakias;

      // Check collisions with branches
      branches.forEach(function(branch, branch_index) {
        var branch_bound = branch.getBounds();

        var branch_broke = 0;

        self.clones.forEach(function(clone) {

          if (branch_broke)
            return;

          var clone_bound = clone.getBounds();

          if (utils.intersect(branch_bound, clone_bound)) {
            branches.splice(branch_index, 1);

            branch_broke = 1;
          }
        });

        return;
      });

      // Check collisions with forks
      forks.forEach(function(fork, fork_index) {
        var fork_head_bound = fork.getHeadBounds();
        var fork_handle_bound = fork.getHandleBounds();

        var fork_broke = 0;

        self.clones.forEach(function(clone) {

          if (fork_broke)
            return;

          var clone_bound = clone.getBounds();

          if (
            utils.intersect(fork_head_bound, clone_bound) ||
            utils.intersect(fork_handle_bound, clone_bound)
          ) {

            // 2 pakias could kill same fork
            // hence just check whether it exists or not
            forks.splice(fork_index, 1);

            fork_broke = 1;
          }

          return;
        });

        return;
      });

      // Check collisions with pakias
      pakias.forEach(function(pakia, pakia_index) {
        var pakia_bound = pakia.getBounds();

        var pakia_dead = 0;

        self.clones.forEach(function(clone) {

          if (pakia_dead)
            return;

          var clone_bound = clone.getBounds();

          if (utils.intersect(pakia_bound, clone_bound)) {
            mit.PakiaUtils.cur_pakia = false;

            pakia_dead = 1;
          }

          return;
        });

        return;
      });

      return;
    }
  };

}());<commit_msg>sirf improvements yaar<commit_after>(function() {

  // There will be only 1 Pappu

  mit.Pappu = {
    x: 50,
    y: 10,
    w: 50,
    h: 50,

    invincible: 0,
    invincibility_start: 0,
    invincibility_time: 0,
    clones: [],

    rotate_angle: 0,

    sprite: {},
    sound: '',

    // Rate of sprite frame change
    // per animation frame.
    change_per_frame: 10,

    fly_frame_count: 0,
    max_fly_frame_count: 10,

    init: function() {
      this.sound = document.getElementById("flap");

      // Initializing Pappu Sprite, lolzzz..!
      // this.sprite = new Image();
      // this.sprite.src = 'img/pappu.png';
      this.sprite = mit.image.pappu;

      //pappu.w = pappu.sprite.width;
      mit.Pappu.w = mit.Pappu.sprite.width;
      mit.Pappu.h = 60;

      // Sprite Frame Count
      mit.Pappu.max_fly_frame_count = 8;
      mit.Pappu.max_fly_frame_count--;

      // Sprite Frame Change Speed.
      // This will affect the flap speed.
      // 1.6 is the perfect value!
      mit.Pappu.change_per_frame = 1.6;

      // X Pos
      mit.Pappu.x = 33;
    },

    undoInvincible: function() {
      this.invincible = 0;
      this.invincibility_start = 0;
      this.invincible_timer = 0;

      mit.ui.invincible_timer.hide();
    },

    draw: function(ctx) {
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;

      if (utils.isInt(cur_sprite_frame)) {
        var source_y = cur_sprite_frame * 60;
      }

      else {
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;

        // Ultra smooth animations
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
        var source_y = old_sprite_frame * 60;
      }

      // console.log(cur_sprite_frame, source_x);

      // Rotation on Flying
      if (mit.flying_up) {
        this.sound.play();

        if (this.rotate_angle > -15) {
          this.rotate_angle -= 2;
        }
      }
      else if (mit.game_over) {
        // draw() is called as long as
        // pappu hasnt hit boundaries and over'ed the game :P

        // Game Over Gugglu!
        this.rotate_angle += 4;
      }
      else {
        if (this.rotate_angle < 30) {
          this.rotate_angle += 2;
        }
      }

      ctx.save();

      ctx.translate(this.x, this.y);
      ctx.translate(this.w/2, this.h/2);
      ctx.rotate(utils.toRadian(this.rotate_angle));

      if (this.invincible) {
        ctx.globalAlpha = 0.4;

        // Current time
        var cur_time = new Date().getTime();
        var time_diff = cur_time - this.invincibility_start;

        var timer_progress = (time_diff/this.invincibility_time) * 100;

        if (timer_progress > 100)
          this.undoInvincible();
        else
          mit.ui.invincible_loader.css('width', timer_progress + '%');

        // console.log(timer_progress)
      }

      ctx.drawImage(
          this.sprite,
          0,
          source_y,
          this.w,
          60,
          -this.w/2,
          -this.h/2,
          this.w,
          60
        );

      ctx.restore();
    },

    drawStatic: function(ctx) {
      var cur_sprite_frame = this.fly_frame_count / this.change_per_frame;

      if (utils.isInt(cur_sprite_frame)) {
        var source_y = cur_sprite_frame * 60;
      }

      else {
        //var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)%this.change_per_frame;

        // Ultra smooth animations
        var old_sprite_frame = parseInt(this.fly_frame_count/this.change_per_frame)
        var source_y = old_sprite_frame * 60;
      }

      this.y = mit.Backgrounds.log_y-42;

      /*ctx.drawImage(
        this.sprite,
        0,
        0,
        this.w,
        60,
        this.x,
        this.y,
        this.w,
        60
      );*/

      ctx.drawImage(
        this.sprite,
        0,
        source_y,
        this.w,
        60,
        this.x,
        this.y,
        this.w,
        60
      );
    },

    updateFlyFrameCount: function(count) {
      if (typeof count !== 'number') {
        this.fly_frame_count++;

        if (parseInt(this.fly_frame_count/this.change_per_frame) > this.max_fly_frame_count) {
          this.fly_frame_count = 0;
        }

        return;
      }

      this.fly_frame_count = count;
    },

    hasReachedBoundary: function(canvas_width, canvas_height) {
      // Crossed Sides ?
      // `c` stands for crossed

      var ctop = (this.y < 0 - this.h);
      var cbtm = (this.y > mit.H);
      var cleft = (this.x < 0);
      var crgt = (this.x > mit.W);

      // return true if crossed any sides
      if (ctop || cbtm || cleft || crgt) {
        return true;
      }

      return false;
    },

    getBounds: function() {
      var b = {};

      b.start_x = this.x;
      b.start_y = this.y;
      b.end_x   = this.x + this.w;
      b.end_y   = this.y + this.h;

      return b;
    },

    createClones: function(count) {
      // This method will be usually called
      // when pappu gathers a 'clone' collectible.

      var pappu_clone;

      for (var i = 0; i < count; i++) {
        pappu_clone = Object.create(mit.Pappu);

        this.clones.push(pappu_clone);
      }

      return;
    },

    drawClones: function(ctx) {

      var self = this;

      self.clones.forEach(function(clone, index) {
        if (clone.x > mit.W || clone.y < 0 || clone.y > mit.H)
          self.clones.splice(index, 1);

        clone.x += utils.randomNumber(5, 10);
        clone.y += utils.randomNumber(-20, 20);

        clone.draw(ctx);
      });

      return;
    },

    checkCloneCollision: function() {

      var self = this;

      // super optimization :P
      if (!self.clones.length)
        return;

      var branches = mit.BranchUtils.branches;
      var forks = mit.ForkUtils.forks;
      var pakias = mit.PakiaUtils.pakias;

      // Check collisions with branches
      branches.forEach(function(branch, branch_index) {
        var branch_bound = branch.getBounds();

        var branch_broke = 0;

        self.clones.forEach(function(clone) {

          if (branch_broke)
            return;

          var clone_bound = clone.getBounds();

          if (utils.intersect(branch_bound, clone_bound)) {
            branches.splice(branch_index, 1);

            branch_broke = 1;
          }
        });

        return;
      });

      // Check collisions with forks
      forks.forEach(function(fork, fork_index) {
        var fork_head_bound = fork.getHeadBounds();
        var fork_handle_bound = fork.getHandleBounds();

        var fork_broke = 0;

        self.clones.forEach(function(clone) {

          if (fork_broke)
            return;

          var clone_bound = clone.getBounds();

          if (
            utils.intersect(fork_head_bound, clone_bound) ||
            utils.intersect(fork_handle_bound, clone_bound)
          ) {

            // 2 pakias could kill same fork
            // hence just check whether it exists or not
            forks.splice(fork_index, 1);

            fork_broke = 1;
          }

          return;
        });

        return;
      });

      // Check collisions with pakias
      pakias.forEach(function(pakia, pakia_index) {
        var pakia_bound = pakia.getBounds();

        var pakia_dead = 0;

        self.clones.forEach(function(clone) {

          if (pakia_dead)
            return;

          var clone_bound = clone.getBounds();

          if (utils.intersect(pakia_bound, clone_bound)) {
            mit.PakiaUtils.cur_pakia = false;

            pakia_dead = 1;
          }

          return;
        });

        return;
      });

      return;
    }
  };

}());<|endoftext|>


<commit_before>calcPerkLevels = function(data) {
	medic(data.damagehealed);
//	support(data.weldingpoints, data.shotgundamage);
	sharp(data.headshotkills);
//	commando(data.stalkerkills, data.bullpupdamage);
//	berzerker(data.meleedamage);
//	firebug(data.flamethrowerdamage);
//	demo(data.explosivesdamage);
}

medic = function(heal) {
	var val;
	var level;
	var progress;

	if (heal < 200) {
		val = heal / 2;
		level = 0;
		progress = 200;
	} else if (heal < 750) {
		val = (heal - 200) / 5.5;
		level = 1;
		progress = 750;
	} else if (heal < 4000) {
		val = (heal - 750) / 32.5;
		level = 2;
		progress = 4000;
	} else if (heal < 12000) {
		val = (heal - 4000) / 80;
		level = 3;
		progress = 12000;
	} else if (heal < 25000) {
		val = (heal - 12000) / 130;
		level = 4;
		progress = 25000;
	} else if (heal < 100000) {
		val = (heal - 25000) / 750;
		level = 5;
		progress = 100000;
	} else {
		val = Math.min((heal - 100000)/ 1000, 100);
		level = 6;
		progress = 200000;
	}

	$('#medic-bar').progressbar({
		value: val
	});

	$('#medic-level').html('
Level: ' + level + '
');
	$('#medic-progress').html('
Progress: ' + heal + ' / ' + progress +' Health Healed
');
}

sharp = function(headshots) {
	var val;
	var level;
	var progress;

	if (headshots < 30) {
		val = (headshots / 30) * 100;
		level = 0;
		progress = 30;
	} else if (headshots < 100) {
                val = (headshots / 30) * 100;
                level = 1;
                progress = 100;
	} else if (headshots < 700) {
                val = (headshots / 30) * 100;
                level = 2;
                progress = 700;
	} else if (headshots < 2500) {
                val = (headshots / 30) * 100;
                level = 3;
                progress = 2500;
	} else if (headshots < 5500) {
                val = (headshots / 30) * 100;
                level = 4;
                progress = 5500;
	} else if (headshots < 8500) {
                val = (headshots / 30) * 100;
                level = 5;
                progress = 8500;
	} else {
                val = (headshots / 30) * 100;
                level = 6;
                progress = 17000;
	}

        $('#sharp-bar').progressbar({
                value: val
        });

        $('#sharp-level').html('
Level: ' + level + '
');
        $('#sharp-progress').html('
Progress: ' + headshots + ' / ' + progress +' Headshots
');
}
<commit_msg>got zerk, fb, demo perks to work<commit_after>calcPerkLevels = function(data) {
	medic(data.damagehealed);
//	support(data.weldingpoints, data.shotgundamage);
	sharp(data.headshotkills);
//	commando(data.stalkerkills, data.bullpupdamage);
	damageperk("berzerker", data.meleedamage);
	damageperk("firebug", data.flamethrowerdamage);
	damageperk("demo", data.explosivesdamage);
}

medic = function(heal) {
	var val;
	var level;
	var progress;

	if (heal < 200) {
		val = heal / 2;
		level = 0;
		progress = 200;
	} else if (heal < 750) {
		val = (heal - 200) / 5.5;
		level = 1;
		progress = 750;
	} else if (heal < 4000) {
		val = (heal - 750) / 32.5;
		level = 2;
		progress = 4000;
	} else if (heal < 12000) {
		val = (heal - 4000) / 80;
		level = 3;
		progress = 12000;
	} else if (heal < 25000) {
		val = (heal - 12000) / 130;
		level = 4;
		progress = 25000;
	} else if (heal < 100000) {
		val = (heal - 25000) / 750;
		level = 5;
		progress = 100000;
	} else {
		val = Math.min((heal - 100000)/ 1000, 100);
		level = 6;
		progress = 200000;
	}

	$('#medic-bar').progressbar({
		value: val
	});

	$('#medic-level').html('
Level: ' + level + '
');
	$('#medic-progress').html('
Progress: ' + heal + ' / ' + progress +' Health Healed
');
}

sharp = function(headshots) {
	var val;
	var level;
	var progress;

	if (headshots < 30) {
		val = (headshots / 30) * 100;
		level = 0;
		progress = 30;
	} else if (headshots < 100) {
                val = (headshots / 30) * 100;
                level = 1;
                progress = 100;
	} else if (headshots < 700) {
                val = (headshots / 30) * 100;
                level = 2;
                progress = 700;
	} else if (headshots < 2500) {
                val = (headshots / 30) * 100;
                level = 3;
                progress = 2500;
	} else if (headshots < 5500) {
                val = (headshots / 30) * 100;
                level = 4;
                progress = 5500;
	} else if (headshots < 8500) {
                val = (headshots / 30) * 100;
                level = 5;
                progress = 8500;
	} else {
                val = (headshots / 30) * 100;
                level = 6;
                progress = 17000;
	}

        $('#sharp-bar').progressbar({
                value: val
        });

        $('#sharp-level').html('
Level: ' + level + '
');
        $('#sharp-progress').html('
Progress: ' + headshots + ' / ' + progress +' Headshots
');
}

damageperk = function(perk, damage) {
	var val;
	var level;
	var progress;

	if (damage < 25000) {
                val = damage / 250;
                level = 0;
                progress = 25000;
	} else if (damage < 100000) {
                val = (damage - 25000) / 750;
                level = 1;
                progress = 100000;
	} else if (damage < 500000) {
                val = (damage - 100000) / 4000;
                level = 2;
                progress = 500000;
	} else if (damage < 1500000) {
                val = (damage - 500000) / 10000;
                level = 3;
                progress = 1500000;
	} else if (damage < 3500000) {
                val = (damage - 1500000) / 20000;
                level = 4;
                progress = 3500000;
	} else if (damage < 5500000) {
                val = (damage - 3500000) / 20000;
                level = 5;
                progress = 5500000;
	} else {
                val = Math.min((damage - 5500000) / 55000, 100);
                level = 6;
                progress = 11000000;
	}

        $('#'+perk+'-bar').progressbar({
                value: val
        });

        $('#'+perk+'-level').html('
Level: ' + level + '
');
        $('#'+perk+'-progress').html('
Progress: ' + damage + ' / ' + progress +' Damage Points Required
');
}
<|endoftext|>


<commit_before>
var showGotoPage;

$(function() {
  $("#btnPlay").click(onPlay);
  $("#btnPause").click(onPause);
  $("#btnStop").click(onStop);
  $("#btnSettings").click(onSettings);
  $("#btnForward").click(onForward);
  $("#btnRewind").click(onRewind);
  $("#decrease-font-size").click(changeFontSize.bind(null, -1));
  $("#increase-font-size").click(changeFontSize.bind(null, +1));
  $("#decrease-window-size").click(changeWindowSize.bind(null, -1));
  $("#increase-window-size").click(changeWindowSize.bind(null, +1));

  updateButtons()
    .then(bgPageInvoke.bind(null, "getPlaybackState"))
    .then(function(state) {
      if (state != "PLAYING") $("#btnPlay").click();
    });
  setInterval(updateButtons, 500);

  refreshSize();
  checkAnnouncements();
});

function handleError(err) {
  if (!err) return;
  if (/^{/.test(err.message)) {
    var errInfo = JSON.parse(err.message);

    $("#status").html(formatError(errInfo)).show();
    $("#status a").click(function() {
      switch ($(this).attr("href")) {
        case "#open-extension-settings":
          brapi.tabs.create({url: "chrome://extensions/?id=" + brapi.runtime.id});
          break;
        case "#request-permissions":
          requestPermissions(errInfo.perms)
            .then(function(granted) {
              if (granted) $("#btnPlay").click();
            })
          break;
        case "#sign-in":
          getAuthToken({interactive: true})
            .then(function(token) {
              if (token) $("#btnPlay").click();
            })
            .catch(function(err) {
              $("#status").text(err.message).show();
            })
          break;
        case "#auth-wavenet":
          requestPermissions(config.wavenetPerms)
            .then(function(granted) {
              if (granted) bgPageInvoke("authWavenet");
            })
          break;
        case "#user-gesture":
          getBackgroundPage()
            .then(callMethod("userGestureActivate"))
            .then(function() {
              $("#btnPlay").click();
            })
          break;
      }
    })

    if (errInfo.code == "error_upload_pdf") {
      setTabUrl(undefined, "https://assets.lsdsoftware.com/read-aloud/page-scripts/pdf-upload.html");
    }
  }
  else {
    $("#status").text(err.message).show();
  }
}

function updateButtons() {
    return Promise.all([
      getSettings(),
      bgPageInvoke("getPlaybackState"),
      bgPageInvoke("getSpeechPosition")
    ])
  .then(spread(function(settings, state, speechPos) {
    $("#imgLoading").toggle(state == "LOADING");
    $("#btnSettings").toggle(state == "STOPPED");
    $("#btnPlay").toggle(state == "PAUSED" || state == "STOPPED");
    $("#btnPause").toggle(state == "PLAYING");
    $("#btnStop").toggle(state == "PAUSED" || state == "PLAYING" || state == "LOADING");
    $("#btnForward, #btnRewind").toggle(state == "PLAYING");
    $("#highlight, #toolbar").toggle(Boolean(settings.showHighlighting != null ? settings.showHighlighting : defaults.showHighlighting) && (state == "LOADING" || state == "PAUSED" || state == "PLAYING"));

    if ((settings.showHighlighting != null ? settings.showHighlighting : defaults.showHighlighting) && speechPos) {
      var pos = speechPos;
      var elem = $("#highlight");
      if (!elem.data("texts") || elem.data("texts").length != pos.texts.length || elem.data("texts").some(function(text,i) {return text != pos.texts[i]})) {
        elem.data({texts: pos.texts, index: -1});
        elem.empty();
        for (var i=0; i<pos.texts.length; i++) {
          var html = escapeHtml(pos.texts[i]).replace(/\r?\n/g, "
");
          $("").html(html).appendTo(elem).css("cursor", "pointer").click(onSeek.bind(null, i));
        }
      }
      if (elem.data("index") != pos.index) {
        elem.data("index", pos.index);
        elem.children(".active").removeClass("active");
        var child = elem.children().eq(pos.index).addClass("active");
        if (child.length) {
        var childTop = child.position().top;
        var childBottom = childTop + child.outerHeight();
        if (childTop < 0 || childBottom >= elem.height()) elem.animate({scrollTop: elem[0].scrollTop + childTop - 10});
        }
      }
    }
  }));
}

function onPlay() {
  $("#status").hide();
  bgPageInvoke("play")
    .then(updateButtons)
    .catch(handleError)
}

function onPause() {
  bgPageInvoke("pause")
    .then(updateButtons)
    .catch(handleError)
}

function onStop() {
  bgPageInvoke("stop")
    .then(updateButtons)
    .catch(handleError)
}

function onSettings() {
  location.href = "options.html?referer=popup.html";
}

function onForward() {
  bgPageInvoke("forward")
    .then(updateButtons)
    .catch(handleError)
}

function onRewind() {
  bgPageInvoke("rewind")
    .then(updateButtons)
    .catch(handleError)
}

function onSeek(n) {
  bgPageInvoke("seek", [n])
    .catch(handleError)
}

function changeFontSize(delta) {
  getSettings(["highlightFontSize"])
    .then(function(settings) {
      var newSize = (settings.highlightFontSize || defaults.highlightFontSize) + delta;
      if (newSize >= 1 && newSize <= 8) return updateSettings({highlightFontSize: newSize}).then(refreshSize);
    })
    .catch(handleError)
}

function changeWindowSize(delta) {
  getSettings(["highlightWindowSize"])
    .then(function(settings) {
      var newSize = (settings.highlightWindowSize || defaults.highlightWindowSize) + delta;
      if (newSize >= 1 && newSize <= 3) return updateSettings({highlightWindowSize: newSize}).then(refreshSize);
    })
    .catch(handleError)
}

function refreshSize() {
  return getSettings(["highlightFontSize", "highlightWindowSize"])
    .then(function(settings) {
      var fontSize = getFontSize(settings);
      var windowSize = getWindowSize(settings);
      $("#highlight").css({
        "font-size": fontSize,
        width: isMobileOS() ? "100%" : windowSize[0],
        height: windowSize[1]
      })
    })
  function getFontSize(settings) {
    switch (settings.highlightFontSize || defaults.highlightFontSize) {
      case 1: return ".9em";
      case 2: return "1em";
      case 3: return "1.1em";
      case 4: return "1.2em";
      case 5: return "1.3em";
      case 6: return "1.4em";
      case 7: return "1.5em";
      default: return "1.6em";
    }
  }
  function getWindowSize(settings) {
    switch (settings.highlightWindowSize || defaults.highlightWindowSize) {
      case 1: return [430, 330];
      case 2: return [550, 420];
      default: return [750, 450];
    }
  }
}

function checkAnnouncements() {
  var now = new Date().getTime();
  getSettings(["announcement"])
    .then(function(settings) {
      var ann = settings.announcement;
      if (ann && ann.expire > now)
        return ann;
      else
        return ajaxGet(config.serviceUrl + "/read-aloud/announcement")
          .then(JSON.parse)
          .then(function(result) {
            result.expire = now + 6*3600*1000;
            if (ann && result.id == ann.id) {
              result.lastShown = ann.lastShown;
              result.disabled = ann.disabled;
            }
            updateSettings({announcement: result});
            return result;
          })
    })
    .then(function(ann) {
      if (ann.text && !ann.disabled) {
        if (!ann.lastShown || now-ann.lastShown > ann.period*60*1000) {
          showAnnouncement(ann);
          ann.lastShown = now;
          updateSettings({announcement: ann});
        }
      }
    })
}

function showAnnouncement(ann) {
  var html = escapeHtml(ann.text).replace(/\[(.*?)\]/g, "$1").replace(/\n/g, "
");
  $("#footer").html(html).addClass("announcement");
  if (ann.disableIfClick)
    $("#footer a").click(function() {
      ann.disabled = true;
      updateSettings({announcement: ann});
    })
}
<commit_msg>#110 show FF/RW buttons while paused<commit_after>
var showGotoPage;

$(function() {
  $("#btnPlay").click(onPlay);
  $("#btnPause").click(onPause);
  $("#btnStop").click(onStop);
  $("#btnSettings").click(onSettings);
  $("#btnForward").click(onForward);
  $("#btnRewind").click(onRewind);
  $("#decrease-font-size").click(changeFontSize.bind(null, -1));
  $("#increase-font-size").click(changeFontSize.bind(null, +1));
  $("#decrease-window-size").click(changeWindowSize.bind(null, -1));
  $("#increase-window-size").click(changeWindowSize.bind(null, +1));

  updateButtons()
    .then(bgPageInvoke.bind(null, "getPlaybackState"))
    .then(function(state) {
      if (state != "PLAYING") $("#btnPlay").click();
    });
  setInterval(updateButtons, 500);

  refreshSize();
  checkAnnouncements();
});

function handleError(err) {
  if (!err) return;
  if (/^{/.test(err.message)) {
    var errInfo = JSON.parse(err.message);

    $("#status").html(formatError(errInfo)).show();
    $("#status a").click(function() {
      switch ($(this).attr("href")) {
        case "#open-extension-settings":
          brapi.tabs.create({url: "chrome://extensions/?id=" + brapi.runtime.id});
          break;
        case "#request-permissions":
          requestPermissions(errInfo.perms)
            .then(function(granted) {
              if (granted) $("#btnPlay").click();
            })
          break;
        case "#sign-in":
          getAuthToken({interactive: true})
            .then(function(token) {
              if (token) $("#btnPlay").click();
            })
            .catch(function(err) {
              $("#status").text(err.message).show();
            })
          break;
        case "#auth-wavenet":
          requestPermissions(config.wavenetPerms)
            .then(function(granted) {
              if (granted) bgPageInvoke("authWavenet");
            })
          break;
        case "#user-gesture":
          getBackgroundPage()
            .then(callMethod("userGestureActivate"))
            .then(function() {
              $("#btnPlay").click();
            })
          break;
      }
    })

    if (errInfo.code == "error_upload_pdf") {
      setTabUrl(undefined, "https://assets.lsdsoftware.com/read-aloud/page-scripts/pdf-upload.html");
    }
  }
  else {
    $("#status").text(err.message).show();
  }
}

function updateButtons() {
    return Promise.all([
      getSettings(),
      bgPageInvoke("getPlaybackState"),
      bgPageInvoke("getSpeechPosition")
    ])
  .then(spread(function(settings, state, speechPos) {
    $("#imgLoading").toggle(state == "LOADING");
    $("#btnSettings").toggle(state == "STOPPED");
    $("#btnPlay").toggle(state == "PAUSED" || state == "STOPPED");
    $("#btnPause").toggle(state == "PLAYING");
    $("#btnStop").toggle(state == "PAUSED" || state == "PLAYING" || state == "LOADING");
    $("#btnForward, #btnRewind").toggle(state == "PLAYING" || state == "PAUSED");
    $("#highlight, #toolbar").toggle(Boolean(settings.showHighlighting != null ? settings.showHighlighting : defaults.showHighlighting) && (state == "LOADING" || state == "PAUSED" || state == "PLAYING"));

    if ((settings.showHighlighting != null ? settings.showHighlighting : defaults.showHighlighting) && speechPos) {
      var pos = speechPos;
      var elem = $("#highlight");
      if (!elem.data("texts") || elem.data("texts").length != pos.texts.length || elem.data("texts").some(function(text,i) {return text != pos.texts[i]})) {
        elem.data({texts: pos.texts, index: -1});
        elem.empty();
        for (var i=0; i<pos.texts.length; i++) {
          var html = escapeHtml(pos.texts[i]).replace(/\r?\n/g, "
");
          $("").html(html).appendTo(elem).css("cursor", "pointer").click(onSeek.bind(null, i));
        }
      }
      if (elem.data("index") != pos.index) {
        elem.data("index", pos.index);
        elem.children(".active").removeClass("active");
        var child = elem.children().eq(pos.index).addClass("active");
        if (child.length) {
        var childTop = child.position().top;
        var childBottom = childTop + child.outerHeight();
        if (childTop < 0 || childBottom >= elem.height()) elem.animate({scrollTop: elem[0].scrollTop + childTop - 10});
        }
      }
    }
  }));
}

function onPlay() {
  $("#status").hide();
  bgPageInvoke("play")
    .then(updateButtons)
    .catch(handleError)
}

function onPause() {
  bgPageInvoke("pause")
    .then(updateButtons)
    .catch(handleError)
}

function onStop() {
  bgPageInvoke("stop")
    .then(updateButtons)
    .catch(handleError)
}

function onSettings() {
  location.href = "options.html?referer=popup.html";
}

function onForward() {
  bgPageInvoke("forward")
    .then(updateButtons)
    .catch(handleError)
}

function onRewind() {
  bgPageInvoke("rewind")
    .then(updateButtons)
    .catch(handleError)
}

function onSeek(n) {
  bgPageInvoke("seek", [n])
    .catch(handleError)
}

function changeFontSize(delta) {
  getSettings(["highlightFontSize"])
    .then(function(settings) {
      var newSize = (settings.highlightFontSize || defaults.highlightFontSize) + delta;
      if (newSize >= 1 && newSize <= 8) return updateSettings({highlightFontSize: newSize}).then(refreshSize);
    })
    .catch(handleError)
}

function changeWindowSize(delta) {
  getSettings(["highlightWindowSize"])
    .then(function(settings) {
      var newSize = (settings.highlightWindowSize || defaults.highlightWindowSize) + delta;
      if (newSize >= 1 && newSize <= 3) return updateSettings({highlightWindowSize: newSize}).then(refreshSize);
    })
    .catch(handleError)
}

function refreshSize() {
  return getSettings(["highlightFontSize", "highlightWindowSize"])
    .then(function(settings) {
      var fontSize = getFontSize(settings);
      var windowSize = getWindowSize(settings);
      $("#highlight").css({
        "font-size": fontSize,
        width: isMobileOS() ? "100%" : windowSize[0],
        height: windowSize[1]
      })
    })
  function getFontSize(settings) {
    switch (settings.highlightFontSize || defaults.highlightFontSize) {
      case 1: return ".9em";
      case 2: return "1em";
      case 3: return "1.1em";
      case 4: return "1.2em";
      case 5: return "1.3em";
      case 6: return "1.4em";
      case 7: return "1.5em";
      default: return "1.6em";
    }
  }
  function getWindowSize(settings) {
    switch (settings.highlightWindowSize || defaults.highlightWindowSize) {
      case 1: return [430, 330];
      case 2: return [550, 420];
      default: return [750, 450];
    }
  }
}

function checkAnnouncements() {
  var now = new Date().getTime();
  getSettings(["announcement"])
    .then(function(settings) {
      var ann = settings.announcement;
      if (ann && ann.expire > now)
        return ann;
      else
        return ajaxGet(config.serviceUrl + "/read-aloud/announcement")
          .then(JSON.parse)
          .then(function(result) {
            result.expire = now + 6*3600*1000;
            if (ann && result.id == ann.id) {
              result.lastShown = ann.lastShown;
              result.disabled = ann.disabled;
            }
            updateSettings({announcement: result});
            return result;
          })
    })
    .then(function(ann) {
      if (ann.text && !ann.disabled) {
        if (!ann.lastShown || now-ann.lastShown > ann.period*60*1000) {
          showAnnouncement(ann);
          ann.lastShown = now;
          updateSettings({announcement: ann});
        }
      }
    })
}

function showAnnouncement(ann) {
  var html = escapeHtml(ann.text).replace(/\[(.*?)\]/g, "$1").replace(/\n/g, "
");
  $("#footer").html(html).addClass("announcement");
  if (ann.disableIfClick)
    $("#footer a").click(function() {
      ann.disabled = true;
      updateSettings({announcement: ann});
    })
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var moment = require('moment');
var http = require('http');

var emailReader = require('./emailReader.js');

var EMAIL_DOMAIN;
emailReader.getAccountInfo(function(accountInfo) {
	if (accountInfo !== undefined && accountInfo.email_addresses.length > 0) {
		var email = accountInfo.email_addresses[0];
		EMAIL_DOMAIN = email.substring(email.indexOf('@') + 1);
	} else {
		console.log('could not read account info!');
	}
});

exports.readEmail = function(callWhenDone) {
	emailReader.readEmail(mapEmailDataToRectangles, callWhenDone);
};

var LAST_RECTANGLES = [];

function mapEmailDataToRectangles(messages, callback) {

	var unreadMessages = _.filter(messages, function(message) {
		return _.contains(message.flags, '\\Seen');
	});
	console.log('Got UNREAD emails from', _.map(unreadMessages, function(message) {
		return message.addresses.from.email + ', ' + message.date;
	}));

	var messagesToday = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') === 0;
	});
	var messagesYesterday = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') === 1;
	});
	var messagesOld = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') > 1;
	});

	function isFromSameDomain(message) {
		return message.addresses.from.email.indexOf(EMAIL_DOMAIN) > -1;
	}

	var countInternalToday = _.countBy(messagesToday, isFromSameDomain);
	var countInternalYesterday = _.countBy(messagesYesterday, isFromSameDomain);
	var countInternalOld = _.countBy(messagesOld, isFromSameDomain);

	var colorInternal = "blue";
	var colorExternal = "red";

	var rectangles = _.compact([
		 createRectangle(countInternalToday.true || 0, colorInternal, 2, ' unread internal mails from today'),
		 createRectangle(countInternalToday.false || 0, colorExternal, 2, ' unread external mails older than yesterday'),
		 createRectangle(countInternalYesterday.true || 0, colorInternal, 1, ' unread internal mails from yesterday'),
		 createRectangle(countInternalYesterday.false || 0, colorExternal, 1, ' unread external mails from yesterday'),
		// createRectangle(countInternalOld.true || 0, colorInternal, 0, ' unread internal mails older than yesterday'),
		// createRectangle(countInternalOld.false || 0, colorExternal, 0, ' unread external mails older than yesterday')

		// fake messages for presentation
		//createRectangle(5, colorInternal, 2, ' unread internal mails from today'),
		//createRectangle(1, colorExternal, 2, ' unread external mails older than yesterday'),
		//createRectangle(3, colorInternal, 1, ' unread internal mails from yesterday'),
		//createRectangle(8, colorExternal, 1, ' unread external mails from yesterday'),
	    createRectangle(16, "blue", 0, ' unread internal mails older than yesterday'),
		createRectangle(7, "red", 0, ' unread internal mails older than yesterday'),
        createRectangle(17, "yellow", 2, ' labeled mails from today'),
		createRectangle(3, "yellow", 1, ' labeled mails from yesterday'),
		createRectangle(3, "yellow", 0, ' labeled mails older than yesterday')
		]);

	var changes = ! _.every(rectangles, function(newRect) {
		var found = false;
		_.each(LAST_RECTANGLES, function(oldRect) {
			if(newRect.color === oldRect.color
				&& newRect.column === newRect.column
				&& newRect.size === newRect.size) {
				found = true;
			}
		});
		return found;
	});

	LAST_RECTANGLES = rectangles;

	callback(rectangles, changes);

};

function createRectangle(count, color, column, info) {
	// if (count === 0) {
	// 	return undefined;
	// }
	var rect = {
		color: color,
		column: column,
		info: count + info
	};

	if(count < 5) {
		rect.size = "small";
	} else if(count < 15) {
		rect.size = "medium";
	} else {
		rect.size = "large";
	}

	return rect;
}
<commit_msg>activated fake data for presentation<commit_after>var _ = require('lodash');
var moment = require('moment');
var http = require('http');
// emails with this label are displayed as a yellow rectangle
var label = 'mondrian;'

var emailReader = require('./emailReader.js');

var EMAIL_DOMAIN;
emailReader.getAccountInfo(function(accountInfo) {
	if (accountInfo !== undefined && accountInfo.email_addresses.length > 0) {
		var email = accountInfo.email_addresses[0];
		EMAIL_DOMAIN = email.substring(email.indexOf('@') + 1);
	} else {
		console.log('could not read account info!');
	}
});

exports.readEmail = function(callWhenDone) {
	emailReader.readEmail(mapEmailDataToRectangles, callWhenDone);
};

var LAST_RECTANGLES = [];

function mapEmailDataToRectangles(messages, callback) {

	// get labeled mails: in folder 'label'

	var unreadMessages = _.filter(messages, function(message) {
		return !_.contains(message.flags, '\\Seen');
	});
	console.log('Got UNREAD emails from', _.map(unreadMessages, function(message) {
		return message.addresses.from.email + ', ' + message.date;
	}));

	var messagesToday = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') === 0;
	});
	var messagesYesterday = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') === 1;
	});
	var messagesOld = _.filter(unreadMessages, function(message) {
		return moment().diff(moment(message.date, 'X'), 'days') > 1;
	});

	function isFromSameDomain(message) {
		return message.addresses.from.email.indexOf(EMAIL_DOMAIN) > -1;
	}

	var countInternalToday = _.countBy(messagesToday, isFromSameDomain);
	var countInternalYesterday = _.countBy(messagesYesterday, isFromSameDomain);
	var countInternalOld = _.countBy(messagesOld, isFromSameDomain);

	var colorInternal = "blue";
	var colorExternal = "red";

	var rectangles = _.compact([
		 //createRectangle(countInternalToday.true || 0, colorInternal, 2, ' unread internal mails from today'),
		 //createRectangle(countInternalToday.false || 0, colorExternal, 2, ' unread external mails older than yesterday'),
		 //createRectangle(countInternalYesterday.true || 0, colorInternal, 1, ' unread internal mails from yesterday'),
		 //createRectangle(countInternalYesterday.false || 0, colorExternal, 1, ' unread external mails from yesterday'),
		// createRectangle(countInternalOld.true || 0, colorInternal, 0, ' unread internal mails older than yesterday'),
		// createRectangle(countInternalOld.false || 0, colorExternal, 0, ' unread external mails older than yesterday')

		// fake messages for presentation
		createRectangle(5, colorInternal, 2, ' unread internal mails from today'),
		createRectangle(1, colorExternal, 2, ' unread external mails older than yesterday'),
		createRectangle(3, colorInternal, 1, ' unread internal mails from yesterday'),
		createRectangle(8, colorExternal, 1, ' unread external mails from yesterday'),
	    createRectangle(16, "blue", 0, ' unread internal mails older than yesterday'),
		createRectangle(7, "red", 0, ' unread internal mails older than yesterday'),
        createRectangle(17, "yellow", 2, ' labeled mails from today'),
		createRectangle(3, "yellow", 1, ' labeled mails from yesterday'),
		createRectangle(3, "yellow", 0, ' labeled mails older than yesterday')
		]);

	var changes = ! _.every(rectangles, function(newRect) {
		var found = false;
		_.each(LAST_RECTANGLES, function(oldRect) {
			if(newRect.color === oldRect.color
				&& newRect.column === newRect.column
				&& newRect.size === newRect.size) {
				found = true;
			}
		});
		return found;
	});

	LAST_RECTANGLES = rectangles;

	callback(rectangles, changes);

};

function createRectangle(count, color, column, info) {
	// if (count === 0) {
	// 	return undefined;
	// }
	var rect = {
		color: color,
		column: column,
		info: count + info
	};

	if(count < 5) {
		rect.size = "small";
	} else if(count < 15) {
		rect.size = "medium";
	} else {
		rect.size = "large";
	}

	return rect;
}
<|endoftext|>


<commit_before>window.onload = function () {
    // Get container elements
    var containers = [
        document.getElementById('currentCurator'),
        document.getElementById('nextCurator'),
        document.getElementById('followingCurator')
    ];
    var successive = document.getElementById('successiveCurators');
    var alertClose = document.getElementById('alert-close');

    // Get file path, add time-stamp to prevent caching
    var filePath = 'https://scratchtools.tk/fpc/api/v2/json/?u=' + new Date().getTime();

    // Init http request
    var xmlHttp = new XMLHttpRequest();

    xmlHttp.ontimeout = function() {
        console.log('Timeout');
        error();
    };

    xmlHttp.onerror = function() {
        console.log('Error');
        error();
    };

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            try {
                downloaded(JSON.parse(xmlHttp.responseText));
            } catch(e) {
                error();
                console.log('Bad JSON syntax');
            }
        }
    };

    xmlHttp.open('GET', filePath, true);
    xmlHttp.timeout = 5000;

    // Send http request
    xmlHttp.send(null);

    // Interpret downloaded data
    function downloaded(result) {
        // Check response was valid
        if (result['response']['code'] === 0) {

            // Load current, following and successive curators
            for (var i = 0; i < 3; i++) {
                if (i < result['curators'].length && result['curators'][i]['user']) {
                    load(result['curators'][i]['user'], containers[i]);
                } else {
                    var date = document.createElement('span');

                    date.className = 'date';
                    date.innerText = 'Start - End';

                    containers[i].parentElement.insertBefore(
                            date,
                            containers[i].parentElement.childNodes[0]
                    );

                    containers[i].title = 'The FPC during this period is currently unknown';
                    containers[i].innerText = 'Unknown';
                }
            }

            // Check if there are successive curators

            if (result['curators'].length > 2) {
                // There are successive curators

                // For each successive curator
                for (var i = 3; i < result['curators'].length; i++) {
                    // Add date
                    successive.innerHTML += 'Start - End';

                    // Check if curator has been suggested
                    if (result['curators'][i]['user']) {
                        // Curator has been suggested

                        // Check if curator is confirmed

                        if (result['curators'][i]['confirmed']) {
                            // Curator is confirmed

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] + '';
                        } else {
                            // Curator isn't confirmed, so display TBC label
                            // and add no link

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] +
                                    ' (TBC)';
                        }
                    } else {
                        // No known FPC for this period

                        // Display unknown message
                        successive.innerHTML +=
                                'Unknown';
                    }
                }

                // Show container for successive curators
                document.getElementById('successiveContainer').className = 'box hover-box';
            }

            // Show notice
            if (result['message']) {
                document.getElementById('alert-text').innerHTML = result['message'];
                document.getElementById('alert').className = 'box';
            }
        } else {
            error();
            console.log(
                    'Error: code ' +
                    result['response']['code'] +
                    ' - ' +
                    result['response']['description']
            );
        }
    }

    // Display error messages in every container
    function error() {
        // TODO: on error, hide containers and show separate div
        containers[0].innerText = 'Error';
        containers[1].innerText = 'Error';
        containers[2].innerText = 'Error';
    }

    // Loads the curator name into the specified container
    function load(user, element) {
        // Check if curator has been suggested

        if (user !== '') {
            // Curator has been suggested for this period

            var date = document.createElement('span');

            date.className = 'date';
            date.innerText = 'Start - End';

            element.parentElement.insertBefore(date, element.parentElement.childNodes[0]);

            if (user.endsWith('?')) {
                //FPC not confirmed

                element.innerHTML =
                        '@' +
                        user.substring(0, user.length - 1) +
                        ' (TBC)';
                element.className = 'gray';
            } else {
                //FPC was confirmed

                element.innerHTML = '@' + user + '';
                element.parentElement.href = 'https://scratch.mit.edu/users/' + user + '/';
                element.className = '';
            }
        }
    }

    // Makes a date human readable
    // Uses browser language to match users prefrences
    function formatDate(d) {
        return d.toLocaleString(navigator.language, {
            day: "numeric",
            month: "short"
        });
    }

    // Add close button click event
    alertClose.onclick = function() {
        document.getElementById('alert').className = 'hidden';
    };
};<commit_msg>Only handle syntax errors<commit_after>window.onload = function () {
    // Get container elements
    var containers = [
        document.getElementById('currentCurator'),
        document.getElementById('nextCurator'),
        document.getElementById('followingCurator')
    ];
    var successive = document.getElementById('successiveCurators');
    var alertClose = document.getElementById('alert-close');

    // Get file path, add time-stamp to prevent caching
    var filePath = 'https://scratchtools.tk/fpc/api/v2/json/?u=' + new Date().getTime();

    // Init http request
    var xmlHttp = new XMLHttpRequest();

    xmlHttp.ontimeout = function() {
        console.log('Timeout');
        error();
    };

    xmlHttp.onerror = function() {
        console.log('Error');
        error();
    };

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            try {
                downloaded(JSON.parse(xmlHttp.responseText));
            } catch(e) {
                if (e instanceof SyntaxError) {
                    error();
                    console.log('Bad JSON syntax');
                } else {
                    throw e;
                }
            }
        }
    };

    xmlHttp.open('GET', filePath, true);
    xmlHttp.timeout = 5000;

    // Send http request
    xmlHttp.send(null);

    // Interpret downloaded data
    function downloaded(result) {
        // Check response was valid
        if (result['response']['code'] === 0) {

            // Load current, following and successive curators
            for (var i = 0; i < 3; i++) {
                if (i < result['curators'].length && result['curators'][i]['user']) {

                    var date = document.createElement('span');

                    date.className = 'date';
                    date.innerText = 'Start - End';

                    containers[i].parentElement.insertBefore(
                            date,
                            containers[i].parentElement.childNodes[0]
                    );

                    // Check if FPC is confirmed

                    if (result['curators'][i]['confirmed']) {
                        //FPC was confirmed

                        containers[i].innerHTML =
                                '@' +
                                result['curators'][i]['user'] +
                                '';

                        containers[i].parentElement.href = result['curators'][i]['suggest_url'];
                        containers[i].className = '';
                    } else {
                        //FPC not confirmed

                        containers[i].innerHTML =
                                '@' +
                                result['curators'][i]['user'] +
                                ' (TBC)';
                        containers[i].className = 'gray';
                    }
                } else {
                    var date = document.createElement('span');

                    date.className = 'date';
                    date.innerText = 'Start - End';

                    containers[i].parentElement.insertBefore(
                            date,
                            containers[i].parentElement.childNodes[0]
                    );

                    containers[i].title = 'The FPC during this period is currently unknown';
                    containers[i].innerText = 'Unknown';
                }
            }

            // Check if there are successive curators

            if (result['curators'].length > 2) {
                // There are successive curators

                // For each successive curator
                for (var i = 3; i < result['curators'].length; i++) {
                    // Add date
                    successive.innerHTML += 'Start - End';

                    // Check if curator has been suggested
                    if (result['curators'][i]['user']) {
                        // Curator has been suggested

                        // Check if curator is confirmed

                        if (result['curators'][i]['confirmed']) {
                            // Curator is confirmed

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] + '';
                        } else {
                            // Curator isn't confirmed, so display TBC label
                            // and add no link

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] +
                                    ' (TBC)';
                        }
                    } else {
                        // No known FPC for this period

                        // Display unknown message
                        successive.innerHTML +=
                                'Unknown';
                    }
                }

                // Show container for successive curators
                document.getElementById('successiveContainer').className = 'box hover-box';
            }

            // Show notice
            if (result['message']) {
                document.getElementById('alert-text').innerHTML = result['message'];
                document.getElementById('alert').className = 'box';
            }
        } else {
            error();
            console.log(
                    'Error: code ' +
                    result['response']['code'] +
                    ' - ' +
                    result['response']['description']
            );
        }
    }

    // Display error messages in every container
    function error() {
        // TODO: on error, hide containers and show separate div
        containers[0].innerText = 'Error';
        containers[1].innerText = 'Error';
        containers[2].innerText = 'Error';
    }

    // Loads the curator name into the specified container
    function load(user, element) {
        // Check if curator has been suggested

        if (user !== '') {
            // Curator has been suggested for this period

            var date = document.createElement('span');

            date.className = 'date';
            date.innerText = 'Start - End';

            element.parentElement.insertBefore(date, element.parentElement.childNodes[0]);

            if (user.endsWith('?')) {
                //FPC not confirmed

                element.innerHTML =
                        '@' +
                        user.substring(0, user.length - 1) +
                        ' (TBC)';
                element.className = 'gray';
            } else {
                //FPC was confirmed

                element.innerHTML = '@' + user + '';
                element.parentElement.href = 'https://scratch.mit.edu/users/' + user + '/';
                element.className = '';
            }
        }
    }

    // Makes a date human readable
    // Uses browser language to match users prefrences
    function formatDate(d) {
        return d.toLocaleString(navigator.language, {
            day: "numeric",
            month: "short"
        });
    }

    // Add close button click event
    alertClose.onclick = function() {
        document.getElementById('alert').className = 'hidden';
    };
};<|endoftext|>


<commit_before>var seconds = 60;                           // Countdown time
var countdown = setInterval(timer, 1000);   // Set timer function to run every second

function timer() {
    seconds = seconds - 1;

    if (seconds <= 0) {
        saveScore(val);
        console.log(getScore());
        window.location.replace("./score.html");
    }

    document.getElementById("timer").innerHTML = seconds;
}
<commit_msg>reduced time limit to 30s<commit_after>var seconds = 30;                           // Countdown time
var countdown = setInterval(timer, 1000);   // Set timer function to run every second

function timer() {
    seconds = seconds - 1;

    if (seconds <= 0) {
        saveScore(val);
        console.log(getScore());
        window.location.replace("./score.html");
    }

    document.getElementById("timer").innerHTML = seconds;
}
<|endoftext|>


<commit_before>// Copyright 2013-2018, University of Colorado Boulder

/**
 * Timer so that other modules can run timing related code through the simulation's requestAnimationFrame. Use its
 * Emitter interface for adding/removing listeners. Note: this is not specific to the running screen, it is global
 * across all screens.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( require => {
  'use strict';

  // modules
  const phetCore = require( 'PHET_CORE/phetCore' );
  const Emitter = require( 'AXON/Emitter' );

  class Timer extends Emitter {

    // @public - Add a listener (which can take a {number} dt argument) to be called back once after the specified time
    // (in milliseconds)
    setTimeout( listener, timeout ) {
      let elapsed = 0;
      const callback = dt => {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= timeout ) {
          listener();
          this.removeListener( callback );
        }
      };
      this.addListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    }

    // @public - Clear a scheduled timeout. If there was no timeout, nothing is done.
    clearTimeout( timeoutID ) {
      if ( this.hasListener( timeoutID ) ) {
        this.removeListener( timeoutID );
      }
    }

    // @public - Add a listener (which can take a {number} dt argument) to be called at specified intervals (in
    // milliseconds)
    setInterval( listener, interval ) {
      let elapsed = 0;
      const callback = dt => {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        while ( elapsed * 1000 >= interval && this.hasListener( callback ) !== -1 ) {
          listener();
          elapsed = elapsed - interval / 1000.0; //Save the leftover time so it won't accumulate
        }
      };
      this.addListener( callback );

      //Return the callback so it can be removed with removeListener
      return callback;
    }

    // @public - Clear a scheduled interval. If there was no interval, nothing is done.
    clearInterval( intervalID ) {
      if ( this.hasListener( intervalID ) ) {
        this.removeListener( intervalID );
      }
    }
  }

  // Register and return a singleton
  return phetCore.register( 'timer', new Timer() );
} );<commit_msg>fix order of modules, https://github.com/phetsims/phet-core/issues/39<commit_after>// Copyright 2013-2018, University of Colorado Boulder

/**
 * Timer so that other modules can run timing related code through the simulation's requestAnimationFrame. Use its
 * Emitter interface for adding/removing listeners. Note: this is not specific to the running screen, it is global
 * across all screens.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( require => {
  'use strict';

  // modules
  const Emitter = require( 'AXON/Emitter' );
  const phetCore = require( 'PHET_CORE/phetCore' );

  class Timer extends Emitter {

    // @public - Add a listener (which can take a {number} dt argument) to be called back once after the specified time
    // (in milliseconds)
    setTimeout( listener, timeout ) {
      let elapsed = 0;
      const callback = dt => {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        if ( elapsed * 1000 >= timeout ) {
          listener();
          this.removeListener( callback );
        }
      };
      this.addListener( callback );

      //Return the callback so it can be removed with removeStepListener
      return callback;
    }

    // @public - Clear a scheduled timeout. If there was no timeout, nothing is done.
    clearTimeout( timeoutID ) {
      if ( this.hasListener( timeoutID ) ) {
        this.removeListener( timeoutID );
      }
    }

    // @public - Add a listener (which can take a {number} dt argument) to be called at specified intervals (in
    // milliseconds)
    setInterval( listener, interval ) {
      let elapsed = 0;
      const callback = dt => {
        elapsed += dt;

        //Convert seconds to ms and see if item has timed out
        while ( elapsed * 1000 >= interval && this.hasListener( callback ) !== -1 ) {
          listener();
          elapsed = elapsed - interval / 1000.0; //Save the leftover time so it won't accumulate
        }
      };
      this.addListener( callback );

      //Return the callback so it can be removed with removeListener
      return callback;
    }

    // @public - Clear a scheduled interval. If there was no interval, nothing is done.
    clearInterval( intervalID ) {
      if ( this.hasListener( intervalID ) ) {
        this.removeListener( intervalID );
      }
    }
  }

  // Register and return a singleton
  return phetCore.register( 'timer', new Timer() );
} );<|endoftext|>