<commit_before>#!/usr/bin/env node
//@flow

// Native
const { join, basename } = require('path')

// Packages
const debug = require('debug')('now:main')
const { existsSync } = require('fs-extra')
const mkdirp = require('mkdirp-promise')
const mri = require('mri')
const chalk = require('chalk')

// Utilities
const error = require('./util/output/error')
const param = require('./util/output/param')
const info = require('./util/output/info')
const getNowDir = require('./get-now-dir')
const getDefaultCfg = require('./get-default-cfg')
const getDefaultAuthCfg = require('./get-default-auth-cfg')
const hp = require('./util/humanize-path')
const providers = require('./providers')
const configFiles = require('./util/config-files')
const checkForUpdates = require('./util/updates')

const NOW_DIR = getNowDir()
const NOW_CONFIG_PATH = configFiles.getConfigFilePath()
const NOW_AUTH_CONFIG_PATH = configFiles.getAuthConfigFilePath()

const GLOBAL_COMMANDS = new Set(['help'])

const main = async (argv_) => {
  await checkForUpdates()

  const argv = mri(argv_, {
    boolean: ['help', 'version'],
    alias: {
      help: 'h',
      version: 'v'
    }
  })

  // the second argument to the command can be a path
  // (as in: `now path/`) or a subcommand / provider
  // (as in: `now ls` or `now aws help`)
  let targetOrSubcommand: ?string = argv._[2]

  // we want to handle version or help directly only
  if (!targetOrSubcommand) {
    if (argv.version) {
      console.log(require('../package').version)
      return 0
    }
  }

  let nowDirExists

  try {
    nowDirExists = existsSync(NOW_DIR)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          'now global directory: ' +
          err.message
      )
    )
    return
  }

  if (!nowDirExists) {
    try {
      await mkdirp(NOW_DIR)
    } catch (err) {
      error(
        'An unexpected error occurred while trying to create the ' +
          `now global directory "${hp(NOW_DIR)}" ` +
          err.message
      )
    }
  }

  let migrated = false
  let configExists

  try {
    configExists = existsSync(NOW_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now config file "${hp(NOW_CONFIG_PATH)}" ` +
          err.message
      )
    )
    return
  }

  let config

  if (configExists) {
    try {
      config = configFiles.readConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now config in "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }

    try {
      config = JSON.parse(config)
    } catch (err) {
      console.error(
        error(
          `An error occurred while trying to parse "${hp(NOW_CONFIG_PATH)}": ` +
            err.message
        )
      )
      return
    }
  } else {
    const results = await getDefaultCfg()

    config = results.config
    migrated = results.migrated

    try {
      configFiles.writeToConfigFile(config)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }
  }

  let authConfigExists

  try {
    authConfigExists = existsSync(NOW_AUTH_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now auth file "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
          err.message
      )
    )
    return
  }

  let authConfig = null

  if (authConfigExists) {
    try {
      authConfig = configFiles.readAuthConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now auth config in "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }

    try {
      authConfig = JSON.parse(authConfig)

      if (!Array.isArray(authConfig.credentials)) {
        console.error(
          error(
            `The content of "${hp(NOW_AUTH_CONFIG_PATH)}" is invalid. ` +
              'No `credentials` list found inside'
          )
        )
        return
      }

      for (const [i, { provider }] of authConfig.credentials.entries()) {
        if (null == provider) {
          console.error(
            error(
              `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
                `Missing \`provider\` key in entry with index ${i}`
            )
          )
          return
        }

        if (!(provider in providers)) {
          console.error(
            error(
              `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
                `Unknown provider "${provider}"`
            )
          )
          return
        }
      }
    } catch (err) {
      console.error(
        error(
          `An error occurred while trying to parse "${hp(
            NOW_AUTH_CONFIG_PATH
          )}": ` + err.message
        )
      )
      return
    }
  } else {
    const results = await getDefaultAuthCfg()

    authConfig = results.config
    migrated = results.migrated

    try {
      configFiles.writeToAuthConfigFile(authConfig)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }
  }

  // Let the user know we migrated the config
  if (migrated) {
    const directory = chalk.grey(join('~', basename(NOW_DIR)))
    console.log(info(`Your credentials and configuration were migrated to ${directory}`))
  }

  // the context object to supply to the providers or the commands
  const ctx = {
    config,
    authConfig,
    argv: argv_
  }

  if (targetOrSubcommand === 'config') {
    const _config = require('./config')
    const subcommand = _config.subcommands.has(argv._[3]) ? argv._[3] : 'help'

    debug(`executing config %s`, subcommand)

    try {
      return _config[subcommand](ctx)
    } catch (err) {
      console.error(
        error(
          `An unexpected error occurred in config ${subcommand}: ${err.stack}`
        )
      )
      return
    }
  }

  let suppliedProvider = null

  // if the target is something like `aws`
  if (targetOrSubcommand && targetOrSubcommand in providers) {
    debug('user supplied a known provider')
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    if (targetPathExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a provider are known'
        )
      )
      return
    }

    suppliedProvider = targetOrSubcommand
    targetOrSubcommand = argv._[3]
  }

  // $FlowFixMe
  let { defaultProvider = null }: { defaultProvider: ?string } = config

  if (null === suppliedProvider) {
    if (null === defaultProvider) {
      // the first provider the user ever logged in to is
      // the default provider
      if (authConfig && authConfig.credentials.length) {
        debug('using first credential as default provider')
        defaultProvider = authConfig.credentials[0].provider
      } else {
        debug(`fallbacking to default now provider 'sh'`)
        defaultProvider = 'sh'
      }
    } else {
      debug('using provider supplied by user', defaultProvider)
      if (!(defaultProvider in providers)) {
        console.error(
          error(
            `The \`defaultProvider\` "${defaultProvider}" supplied in ` +
              `"${NOW_CONFIG_PATH}" is not a valid provider`
          )
        )
        return
      }
    }
  }

  const providerName = suppliedProvider || defaultProvider
  const provider: Object = providers[providerName]

  let subcommand

  // we check if we are deploying something
  if (targetOrSubcommand) {
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    const subcommandExists =
      GLOBAL_COMMANDS.has(targetOrSubcommand) ||
      provider.subcommands.has(targetOrSubcommand)

    if (targetPathExists && subcommandExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a subcommand are known'
        )
      )
      return
    }

    if (subcommandExists) {
      debug('user supplied known subcommand', targetOrSubcommand)
      subcommand = targetOrSubcommand
    } else {
      debug('user supplied a possible target for deployment')
      // our default command is deployment
      // at this point we're
      subcommand = 'deploy'
    }
  } else {
    debug('user supplied no target, defaulting to deploy')
    subcommand = 'deploy'
  }

  if (subcommand === 'help') {
    subcommand = argv._[3] || 'deploy'
    ctx.argv.push('-h')
  }

  // If no credentials are set at all, prompt for
  // login to the .sh provider
  if (!authConfig.credentials.length && !ctx.argv.includes('-h')) {
    console.log(info(`No existing credentials found. Please log in:`))

    subcommand = 'login'
    ctx.argv[2] = 'login'

    // Ensure that sub commands lead to login as well, if
    // no credentials are defined
    ctx.argv = ctx.argv.splice(0, 3)
  }

  try {
    await provider[subcommand](ctx)
  } catch (err) {
    console.error(
      error(
        `An unexpected error occurred in provider ${subcommand}: ${err.stack}`
      )
    )
  }

  if (providerName === 'gcp') {
    process.exit()
  }
}

debug('start')

const handleRejection = err => {
  debug('handling rejection')
  if (err) {
    if (err instanceof Error) {
      handleUnexpected(err)
    } else {
      console.error(error(`An unexpected rejection occurred\n  ${err}`))
    }
  } else {
    console.error(error('An unexpected empty rejection occurred'))
  }
  process.exit(1)
}

const handleUnexpected = err => {
  debug('handling unexpected error')
  console.error(
    error(`An unexpected error occurred!\n  ${err.stack} ${err.stack}`)
  )
  process.exit(1)
}

process.on('unhandledRejection', handleRejection)
process.on('uncaughtException', handleUnexpected)

// Don't use `.then` here. We need to shutdown gracefully, otherwise
// sub commands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv).catch(handleUnexpected)
<commit_msg>Don't prompt for login if token was defined (#797)<commit_after>#!/usr/bin/env node
//@flow

// Native
const { join, basename } = require('path')

// Packages
const debug = require('debug')('now:main')
const { existsSync } = require('fs-extra')
const mkdirp = require('mkdirp-promise')
const mri = require('mri')
const chalk = require('chalk')

// Utilities
const error = require('./util/output/error')
const param = require('./util/output/param')
const info = require('./util/output/info')
const getNowDir = require('./get-now-dir')
const getDefaultCfg = require('./get-default-cfg')
const getDefaultAuthCfg = require('./get-default-auth-cfg')
const hp = require('./util/humanize-path')
const providers = require('./providers')
const configFiles = require('./util/config-files')
const checkForUpdates = require('./util/updates')

const NOW_DIR = getNowDir()
const NOW_CONFIG_PATH = configFiles.getConfigFilePath()
const NOW_AUTH_CONFIG_PATH = configFiles.getAuthConfigFilePath()

const GLOBAL_COMMANDS = new Set(['help'])

const main = async (argv_) => {
  await checkForUpdates()

  const argv = mri(argv_, {
    boolean: ['help', 'version'],
    alias: {
      help: 'h',
      version: 'v'
    }
  })

  // the second argument to the command can be a path
  // (as in: `now path/`) or a subcommand / provider
  // (as in: `now ls` or `now aws help`)
  let targetOrSubcommand: ?string = argv._[2]

  // we want to handle version or help directly only
  if (!targetOrSubcommand) {
    if (argv.version) {
      console.log(require('../package').version)
      return 0
    }
  }

  let nowDirExists

  try {
    nowDirExists = existsSync(NOW_DIR)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          'now global directory: ' +
          err.message
      )
    )
    return
  }

  if (!nowDirExists) {
    try {
      await mkdirp(NOW_DIR)
    } catch (err) {
      error(
        'An unexpected error occurred while trying to create the ' +
          `now global directory "${hp(NOW_DIR)}" ` +
          err.message
      )
    }
  }

  let migrated = false
  let configExists

  try {
    configExists = existsSync(NOW_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now config file "${hp(NOW_CONFIG_PATH)}" ` +
          err.message
      )
    )
    return
  }

  let config

  if (configExists) {
    try {
      config = configFiles.readConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now config in "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }

    try {
      config = JSON.parse(config)
    } catch (err) {
      console.error(
        error(
          `An error occurred while trying to parse "${hp(NOW_CONFIG_PATH)}": ` +
            err.message
        )
      )
      return
    }
  } else {
    const results = await getDefaultCfg()

    config = results.config
    migrated = results.migrated

    try {
      configFiles.writeToConfigFile(config)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }
  }

  let authConfigExists

  try {
    authConfigExists = existsSync(NOW_AUTH_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now auth file "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
          err.message
      )
    )
    return
  }

  let authConfig = null

  if (authConfigExists) {
    try {
      authConfig = configFiles.readAuthConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now auth config in "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }

    try {
      authConfig = JSON.parse(authConfig)

      if (!Array.isArray(authConfig.credentials)) {
        console.error(
          error(
            `The content of "${hp(NOW_AUTH_CONFIG_PATH)}" is invalid. ` +
              'No `credentials` list found inside'
          )
        )
        return
      }

      for (const [i, { provider }] of authConfig.credentials.entries()) {
        if (null == provider) {
          console.error(
            error(
              `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
                `Missing \`provider\` key in entry with index ${i}`
            )
          )
          return
        }

        if (!(provider in providers)) {
          console.error(
            error(
              `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
                `Unknown provider "${provider}"`
            )
          )
          return
        }
      }
    } catch (err) {
      console.error(
        error(
          `An error occurred while trying to parse "${hp(
            NOW_AUTH_CONFIG_PATH
          )}": ` + err.message
        )
      )
      return
    }
  } else {
    const results = await getDefaultAuthCfg()

    authConfig = results.config
    migrated = results.migrated

    try {
      configFiles.writeToAuthConfigFile(authConfig)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return
    }
  }

  // Let the user know we migrated the config
  if (migrated) {
    const directory = chalk.grey(join('~', basename(NOW_DIR)))
    console.log(info(`Your credentials and configuration were migrated to ${directory}`))
  }

  // the context object to supply to the providers or the commands
  const ctx = {
    config,
    authConfig,
    argv: argv_
  }

  if (targetOrSubcommand === 'config') {
    const _config = require('./config')
    const subcommand = _config.subcommands.has(argv._[3]) ? argv._[3] : 'help'

    debug(`executing config %s`, subcommand)

    try {
      return _config[subcommand](ctx)
    } catch (err) {
      console.error(
        error(
          `An unexpected error occurred in config ${subcommand}: ${err.stack}`
        )
      )
      return
    }
  }

  let suppliedProvider = null

  // if the target is something like `aws`
  if (targetOrSubcommand && targetOrSubcommand in providers) {
    debug('user supplied a known provider')
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    if (targetPathExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a provider are known'
        )
      )
      return
    }

    suppliedProvider = targetOrSubcommand
    targetOrSubcommand = argv._[3]
  }

  // $FlowFixMe
  let { defaultProvider = null }: { defaultProvider: ?string } = config

  if (null === suppliedProvider) {
    if (null === defaultProvider) {
      // the first provider the user ever logged in to is
      // the default provider
      if (authConfig && authConfig.credentials.length) {
        debug('using first credential as default provider')
        defaultProvider = authConfig.credentials[0].provider
      } else {
        debug(`fallbacking to default now provider 'sh'`)
        defaultProvider = 'sh'
      }
    } else {
      debug('using provider supplied by user', defaultProvider)
      if (!(defaultProvider in providers)) {
        console.error(
          error(
            `The \`defaultProvider\` "${defaultProvider}" supplied in ` +
              `"${NOW_CONFIG_PATH}" is not a valid provider`
          )
        )
        return
      }
    }
  }

  const providerName = suppliedProvider || defaultProvider
  const provider: Object = providers[providerName]

  let subcommand

  // we check if we are deploying something
  if (targetOrSubcommand) {
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    const subcommandExists =
      GLOBAL_COMMANDS.has(targetOrSubcommand) ||
      provider.subcommands.has(targetOrSubcommand)

    if (targetPathExists && subcommandExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a subcommand are known'
        )
      )
      return
    }

    if (subcommandExists) {
      debug('user supplied known subcommand', targetOrSubcommand)
      subcommand = targetOrSubcommand
    } else {
      debug('user supplied a possible target for deployment')
      // our default command is deployment
      // at this point we're
      subcommand = 'deploy'
    }
  } else {
    debug('user supplied no target, defaulting to deploy')
    subcommand = 'deploy'
  }

  if (subcommand === 'help') {
    subcommand = argv._[3] || 'deploy'
    ctx.argv.push('-h')
  }

  // If no credentials are set at all, prompt for
  // login to the .sh provider
  if (
    !authConfig.credentials.length &&
    !ctx.argv.includes('-h') && !ctx.argv.includes('--help') &&
    !ctx.argv.includes('-t') && !ctx.argv.includes('--token')
  ) {
    console.log(info(`No existing credentials found. Please log in:`))

    subcommand = 'login'
    ctx.argv[2] = 'login'

    // Ensure that sub commands lead to login as well, if
    // no credentials are defined
    ctx.argv = ctx.argv.splice(0, 3)
  }

  try {
    await provider[subcommand](ctx)
  } catch (err) {
    console.error(
      error(
        `An unexpected error occurred in provider ${subcommand}: ${err.stack}`
      )
    )
  }

  if (providerName === 'gcp') {
    process.exit()
  }
}

debug('start')

const handleRejection = err => {
  debug('handling rejection')
  if (err) {
    if (err instanceof Error) {
      handleUnexpected(err)
    } else {
      console.error(error(`An unexpected rejection occurred\n  ${err}`))
    }
  } else {
    console.error(error('An unexpected empty rejection occurred'))
  }
  process.exit(1)
}

const handleUnexpected = err => {
  debug('handling unexpected error')
  console.error(
    error(`An unexpected error occurred!\n  ${err.stack} ${err.stack}`)
  )
  process.exit(1)
}

process.on('unhandledRejection', handleRejection)
process.on('uncaughtException', handleUnexpected)

// Don't use `.then` here. We need to shutdown gracefully, otherwise
// sub commands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv).catch(handleUnexpected)
<|endoftext|>


<commit_before>//Preferences API:
//  D.prf.foo()                              // getter
//  D.prf.foo(123)                           // setter
//  D.prf.foo(function(newValue,oldValue){}) // add "on change" listener
//  D.prf.foo.toggle()                       // convenience function for booleans (numbers 0 and 1)
//  D.prf.foo.getDefault()                   // retrieve default value
'use strict'
D.prf={}
;[//name                 default (type is determined from default value; setter enforces type and handles encoding)
  ['autoCloseBlocks',    1], //whether to insert :end after :if,:for,etc when Enter is pressed
  ['autoCloseBlocksEnd', 0], //0: close blocks with ":EndIf",":EndFor",etc;  1: close blocks only with ":End"
  ['autoCloseBrackets',  1], //whether to insert {}[]() in pairs
  ['autocompletion',     1],
  ['blockCursor',        0], // use block cursor selection?
  ['autocompletionDelay',500],
  ['colourScheme',       'Default'], //name of the active colour scheme
  ['colourSchemes',      []],//objects describing user-defined colour schemes
  ['favs',               [{type:'connect'}]],
  ['floating',           0], //floating editor and tracer windows
  ['floatOnTop',         0], //try to keep floating windows on top of the session
  ['fold',               1], //code folding
  ['ime',                1], //switch to dyalog IME when RIDE starts (Windows-only)
  ['indent',             4], //-1 disables autoindent
  ['indentComments',     0], //whether to touch comment-only lines at all
  ['indentMethods',      -1],//-1 makes methods use the same indent as all other blocks
  ['indentOnOpen',       1], //whether to re-indent source code on editor open
  ['kbdLocale',          ''],//e.g. "US", "GB"
  ['keys',               {}],//a mapping between commands and keystrokes, only diffs from the defaults
  ['lbar',               1], //show language bar
  ['lineNums',           1],
  ['matchBrackets',      1], //whether to highlight matching brackets
  ['otherExe',           ''],//content of the "exe" text box "Other..." is selected in the Connect page
  ['prefixKey',          '`'],
  ['prefixMaps',         {}],//per-locale strings of pairs of characters - diffs from the default map for that locale
  ['pfkeys',             ['','','','','','','','','','','','','']], //command strings for pfkeys
  ['selectedExe',        ''],//which interpreter is selected in dropdown in the Connect page?
  ['title',              '{WSID}'], //a.k.a. "caption"
  ['valueTips',          1], //value tips
  ['squiggleTips',       1],
  ['wrap',               0], //line wrapping in session
  ['wse',                0], //show workspace explorer?
  ['zoom',               0],
  ['menu',
    '# see below for syntax'+
    '\n'+
    '\nDyalog                          {mac}'+
    '\n  About Dyalog             =ABT'+
    '\n  -'+
    '\n  Preferences              =PRF'+
    '\n&File                           {!browser}'+
    '\n  New &Session             =NEW'+
    '\n  &Connect...              =CNC'+
    '\n  -                             {!mac}'+
    '\n  &Quit                    =QIT {!mac}'+
    '\n&Edit'+
    '\n  Cut                      =CT  {!mac&&!browser}'+
    '\n  Copy                     =CP  {!mac&&!browser}'+
    '\n  Paste                    =PT  {!mac&&!browser}'+
    '\n  Undo                     =UND {!browser}'+
    '\n  Redo                     =RDO {!browser}'+
    '\n  -                             {!mac&&!browser}'+
    '\n  Preferences              =PRF {!mac}'+
    '\n  Select All               =SA  {mac}'+
    '\n&View'+
    '\n  Show Language Bar        =LBR'+
    '\n  Show Workspace Explorer  =WSE'+
    '\n  Floating Edit Windows    =FLT'+
//    '\n  Editors on Top           =TOP {!browser}'+
    '\n  Line Wrapping in Session =WRP'+
    '\n  -                             {!browser}'+
    '\n  Increase Font Size       =ZMI {!browser}'+
    '\n  Decrease Font Size       =ZMO {!browser}'+
    '\n  Reset Font Size          =ZMR {!browser}'+
//    '\n  -'+
    '\n&Actions'+
    '\n  Weak Interrupt           =WI'+
    '\n  Strong Interrupt         =SI'+
    '\n&Window                         {mac}'+
    '\n&Help'+
    '\n  Dyalog Help              =http://help.dyalog.com/'+
    '\n  Documentation Centre     =http://dyalog.com/documentation.htm'+
    '\n  -'+
    '\n  Dyalog Website           =http://dyalog.com/'+
    '\n  MyDyalog                 =https://my.dyalog.com/'+
    '\n  -'+
    '\n  Dyalog Forum             =http://www.dyalog.com/forum'+
    '\n  -                             {!mac}'+
    '\n  About                    =ABT {!mac}'+
    '\n'+
    '\n# Syntax:'+
    '\n#   &x   access key, alt+x'+
    '\n#   =CMD command code; some are special:'+
    '\n#          LBR FLT WRP TOP WSE render as checkboxes'+
    '\n#   =http://example.com/  open a URL'+
    '\n#   {}   conditional display, a boolean expression'+
    '\n#          operators: && || ! ( )'+
    '\n#          variables: browser mac win'+
    '\n#   -    separator (when alone)'+
    '\n#   #    comment'+
    '\n'+
    '\n# The =PRF ("Preferences") menu item must be present.'
  ]
].forEach(function(kd){
  var k=kd[0], d=kd[1], t=typeof d, l=[], //k:preference name (key), d:default value, t:type, l:listeners
      str=t==='object'?JSON.stringify:function(x){return''+x}, //stringifier function
      sd=str(d),
      p=D.prf[k]=function(x){
        if(typeof x==='function'){l.push(x);return} //add listener
        if(!arguments.length){var r=D.db.getItem(k);return r==null?d:t==='number'?+r:t==='object'?JSON.parse(r):r} //get
        //set:
        x=t==='number'?+x:t==='string'?(''+x):(typeof x==='string'?JSON.parse(x):x) //coerce x to type t
        var sx=str(x);if(sx===sd)sx=''           //convert to a string; if default, use ''
        var sy=D.db.getItem(k)||''               //old value, stringified
        if(sx===sy)return x
        if(l.length)var y=p()                    //old value as an object (only needed if we have any listeners)
        sx?D.db.setItem(k,sx):D.db.removeItem(k) //store
        for(var i=0;i<l.length;i++)l[i](x,y)     //notify listeners
        return x
      }
  p.getDefault=function(){return d}
  p.toggle=function(){return p(!p())}
})

D.db=!node_require?localStorage:(function(){
  var rq=node_require,crypto=rq('crypto'),fs=rq('fs'),el=rq('electron').remote,elw=el.getGlobal('elw')
  //file-backed storage with API similar to that of localStorage
  var k=[],v=[] //keys and values
  var db={key       :function(x)  {return k[x]},
          getItem   :function(x)  {var i=k.indexOf(x);return i<0?null:v[i]},
          setItem   :function(x,y){var i=k.indexOf(x);if(i<0){k.push(x);v.push(y)}else{v[i]=y};dbWrite()},
          removeItem:function(x)  {var i=k.indexOf(x);if(i>=0){k.splice(i,1);v.splice(i,1);dbWrite()}},
          _getAll   :function()   {var r={};for(var i=0;i<k.length;i++)r[k[i]]=v[i];return r}}
  Object.defineProperty(db,'length',{get:function(){return k.length}})
  var d=el.app.getPath('userData'), f=d+'/prefs.json', ts=0
  elw.on('focus',function(){
    if(!fs.existsSync(f))return
    var ts1=+fs.statSync(f).mtime;if(ts1===ts||!confirm('Preferences have been modified. Reload?')){ts=ts1;return}
    var h=JSON.parse(fs.readFileSync(f,'utf8'));for(var x in h)D.prf[x](h[x])
  })
  try{
    if(fs.existsSync(f)){var h=JSON.parse(fs.readFileSync(f,'utf8'));for(var x in h){k.push(x);v.push(h[x])}
                         ts=+fs.statSync(f).mtime}
  }catch(e){console.error(e)}
  var dbWrite=function(){
    var s='{\n'+k.map(function(x,i){return'  '+JSON.stringify(x)+':'+JSON.stringify(v[i])}).sort().join(',\n')+'\n}\n'
    fs.writeFileSync(f,s);ts=+fs.statSync(f).mtime
  }
  return db
}())

if(D.win&&D.db.getItem('ime')!=='0'){
  var setImeExe=process.execPath.replace(/[^\\\/]+$/,'set-ime.exe')
  var fs=node_require('fs'),spawn=node_require('child_process').spawn
  fs.existsSync(setImeExe)&&spawn(setImeExe,[process.pid],{stdio:['ignore','ignore','ignore']})
}
<commit_msg>enforce block cursor as a default<commit_after>//Preferences API:
//  D.prf.foo()                              // getter
//  D.prf.foo(123)                           // setter
//  D.prf.foo(function(newValue,oldValue){}) // add "on change" listener
//  D.prf.foo.toggle()                       // convenience function for booleans (numbers 0 and 1)
//  D.prf.foo.getDefault()                   // retrieve default value
'use strict'
D.prf={}
;[//name                 default (type is determined from default value; setter enforces type and handles encoding)
  ['autoCloseBlocks',    1], //whether to insert :end after :if,:for,etc when Enter is pressed
  ['autoCloseBlocksEnd', 0], //0: close blocks with ":EndIf",":EndFor",etc;  1: close blocks only with ":End"
  ['autoCloseBrackets',  1], //whether to insert {}[]() in pairs
  ['autocompletion',     1],
  ['blockCursor',        1], // use block cursor selection?
  ['autocompletionDelay',500],
  ['colourScheme',       'Default'], //name of the active colour scheme
  ['colourSchemes',      []],//objects describing user-defined colour schemes
  ['favs',               [{type:'connect'}]],
  ['floating',           0], //floating editor and tracer windows
  ['floatOnTop',         0], //try to keep floating windows on top of the session
  ['fold',               1], //code folding
  ['ime',                1], //switch to dyalog IME when RIDE starts (Windows-only)
  ['indent',             4], //-1 disables autoindent
  ['indentComments',     0], //whether to touch comment-only lines at all
  ['indentMethods',      -1],//-1 makes methods use the same indent as all other blocks
  ['indentOnOpen',       1], //whether to re-indent source code on editor open
  ['kbdLocale',          ''],//e.g. "US", "GB"
  ['keys',               {}],//a mapping between commands and keystrokes, only diffs from the defaults
  ['lbar',               1], //show language bar
  ['lineNums',           1],
  ['matchBrackets',      1], //whether to highlight matching brackets
  ['otherExe',           ''],//content of the "exe" text box "Other..." is selected in the Connect page
  ['prefixKey',          '`'],
  ['prefixMaps',         {}],//per-locale strings of pairs of characters - diffs from the default map for that locale
  ['pfkeys',             ['','','','','','','','','','','','','']], //command strings for pfkeys
  ['selectedExe',        ''],//which interpreter is selected in dropdown in the Connect page?
  ['title',              '{WSID}'], //a.k.a. "caption"
  ['valueTips',          1], //value tips
  ['squiggleTips',       1],
  ['wrap',               0], //line wrapping in session
  ['wse',                0], //show workspace explorer?
  ['zoom',               0],
  ['menu',
    '# see below for syntax'+
    '\n'+
    '\nDyalog                          {mac}'+
    '\n  About Dyalog             =ABT'+
    '\n  -'+
    '\n  Preferences              =PRF'+
    '\n&File                           {!browser}'+
    '\n  New &Session             =NEW'+
    '\n  &Connect...              =CNC'+
    '\n  -                             {!mac}'+
    '\n  &Quit                    =QIT {!mac}'+
    '\n&Edit'+
    '\n  Cut                      =CT  {!mac&&!browser}'+
    '\n  Copy                     =CP  {!mac&&!browser}'+
    '\n  Paste                    =PT  {!mac&&!browser}'+
    '\n  Undo                     =UND {!browser}'+
    '\n  Redo                     =RDO {!browser}'+
    '\n  -                             {!mac&&!browser}'+
    '\n  Preferences              =PRF {!mac}'+
    '\n  Select All               =SA  {mac}'+
    '\n&View'+
    '\n  Show Language Bar        =LBR'+
    '\n  Show Workspace Explorer  =WSE'+
    '\n  Floating Edit Windows    =FLT'+
//    '\n  Editors on Top           =TOP {!browser}'+
    '\n  Line Wrapping in Session =WRP'+
    '\n  -                             {!browser}'+
    '\n  Increase Font Size       =ZMI {!browser}'+
    '\n  Decrease Font Size       =ZMO {!browser}'+
    '\n  Reset Font Size          =ZMR {!browser}'+
//    '\n  -'+
    '\n&Actions'+
    '\n  Weak Interrupt           =WI'+
    '\n  Strong Interrupt         =SI'+
    '\n&Window                         {mac}'+
    '\n&Help'+
    '\n  Dyalog Help              =http://help.dyalog.com/'+
    '\n  Documentation Centre     =http://dyalog.com/documentation.htm'+
    '\n  -'+
    '\n  Dyalog Website           =http://dyalog.com/'+
    '\n  MyDyalog                 =https://my.dyalog.com/'+
    '\n  -'+
    '\n  Dyalog Forum             =http://www.dyalog.com/forum'+
    '\n  -                             {!mac}'+
    '\n  About                    =ABT {!mac}'+
    '\n'+
    '\n# Syntax:'+
    '\n#   &x   access key, alt+x'+
    '\n#   =CMD command code; some are special:'+
    '\n#          LBR FLT WRP TOP WSE render as checkboxes'+
    '\n#   =http://example.com/  open a URL'+
    '\n#   {}   conditional display, a boolean expression'+
    '\n#          operators: && || ! ( )'+
    '\n#          variables: browser mac win'+
    '\n#   -    separator (when alone)'+
    '\n#   #    comment'+
    '\n'+
    '\n# The =PRF ("Preferences") menu item must be present.'
  ]
].forEach(function(kd){
  var k=kd[0], d=kd[1], t=typeof d, l=[], //k:preference name (key), d:default value, t:type, l:listeners
      str=t==='object'?JSON.stringify:function(x){return''+x}, //stringifier function
      sd=str(d),
      p=D.prf[k]=function(x){
        if(typeof x==='function'){l.push(x);return} //add listener
        if(!arguments.length){var r=D.db.getItem(k);return r==null?d:t==='number'?+r:t==='object'?JSON.parse(r):r} //get
        //set:
        x=t==='number'?+x:t==='string'?(''+x):(typeof x==='string'?JSON.parse(x):x) //coerce x to type t
        var sx=str(x);if(sx===sd)sx=''           //convert to a string; if default, use ''
        var sy=D.db.getItem(k)||''               //old value, stringified
        if(sx===sy)return x
        if(l.length)var y=p()                    //old value as an object (only needed if we have any listeners)
        sx?D.db.setItem(k,sx):D.db.removeItem(k) //store
        for(var i=0;i<l.length;i++)l[i](x,y)     //notify listeners
        return x
      }
  p.getDefault=function(){return d}
  p.toggle=function(){return p(!p())}
})

D.db=!node_require?localStorage:(function(){
  var rq=node_require,crypto=rq('crypto'),fs=rq('fs'),el=rq('electron').remote,elw=el.getGlobal('elw')
  //file-backed storage with API similar to that of localStorage
  var k=[],v=[] //keys and values
  var db={key       :function(x)  {return k[x]},
          getItem   :function(x)  {var i=k.indexOf(x);return i<0?null:v[i]},
          setItem   :function(x,y){var i=k.indexOf(x);if(i<0){k.push(x);v.push(y)}else{v[i]=y};dbWrite()},
          removeItem:function(x)  {var i=k.indexOf(x);if(i>=0){k.splice(i,1);v.splice(i,1);dbWrite()}},
          _getAll   :function()   {var r={};for(var i=0;i<k.length;i++)r[k[i]]=v[i];return r}}
  Object.defineProperty(db,'length',{get:function(){return k.length}})
  var d=el.app.getPath('userData'), f=d+'/prefs.json', ts=0
  elw.on('focus',function(){
    if(!fs.existsSync(f))return
    var ts1=+fs.statSync(f).mtime;if(ts1===ts||!confirm('Preferences have been modified. Reload?')){ts=ts1;return}
    var h=JSON.parse(fs.readFileSync(f,'utf8'));for(var x in h)D.prf[x](h[x])
  })
  try{
    if(fs.existsSync(f)){var h=JSON.parse(fs.readFileSync(f,'utf8'));for(var x in h){k.push(x);v.push(h[x])}
                         ts=+fs.statSync(f).mtime}
  }catch(e){console.error(e)}
  var dbWrite=function(){
    var s='{\n'+k.map(function(x,i){return'  '+JSON.stringify(x)+':'+JSON.stringify(v[i])}).sort().join(',\n')+'\n}\n'
    fs.writeFileSync(f,s);ts=+fs.statSync(f).mtime
  }
  return db
}())

if(D.win&&D.db.getItem('ime')!=='0'){
  var setImeExe=process.execPath.replace(/[^\\\/]+$/,'set-ime.exe')
  var fs=node_require('fs'),spawn=node_require('child_process').spawn
  fs.existsSync(setImeExe)&&spawn(setImeExe,[process.pid],{stdio:['ignore','ignore','ignore']})
}
<|endoftext|>


<commit_before>/*
* Pym.js is library that resizes an iframe based on the width of the parent and the resulting height of the child.
* Check out the docs at http://foo or the readme at README.md for usage.
*/

var pym = (function() {
    var lib = {};

    var _isSafeMessage = function(e, settings) {
        /*
        * Check the message to make sure it comes from an acceptable xdomain.
        * Defaults to '*' but can be overriden in config.
        */
        if (settings.xdomain !== '*') {
            // If origin doesn't match our xdomain, return.
            if (!e.origin.match(new RegExp(settings.xdomain + '$'))) { return; }
        }

        return true;
    }

    lib.Parent = function(id, url, config) {
        /*
        * A global function for setting up a responsive parent.
        * Use the config object to override the default settings.
        */
        this.id = id;
        this.url = url;
        this.el = document.getElementById(id);

        this.settings = {
            xdomain: '*'
        };

        this.constructIframe = function() {
            /*
            * A function which handles constructing an iframe inside a given element.
            */

            // Calculate the width of this element.
            var width = this.el.offsetWidth.toString();

            // Create an iframe element attached to the document.
            var node = document.createElement("iframe");

            // Save fragment id
            var hash = '';
            var hashIndex = this.url.indexOf('#');

            console.log(hashIndex, this.url, hash);
            if (hashIndex > -1) {
                hash = this.url.substring(hashIndex, this.url.length);
                this.url = this.url.substring(0, hashIndex);
            }

            // If the URL contains querystring bits, use them.
            // Otherwise, just create a set of valid params.
            if (this.url.indexOf('?') < 0) {
                this.url += '?';
            } else {
                this.url += '&';
            }

            // Append the initial width as a querystring parameter, and the fragment id
            node.src = this.url + 'initialWidth=' + width + '&childId=' + this.id + hash;

            // Set some attributes to this proto-iframe.
            node.setAttribute('width', '100%');
            node.setAttribute('scrolling', 'no');
            node.setAttribute('marginheight', '0');
            node.setAttribute('frameborder', '0');

            // Append the iframe to our element.
            this.el.appendChild(node);

            // Add an event listener that will handle redrawing the child on resize.
            var that = this;
            window.addEventListener('resize', function(e) {
                that.sendWidthToChild();
            });
        }

        this.processChildMessage = function(e) {
            /*
            * Process a new message from the child.
            * Used to set the height on our iframe.
            */
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Grab the message from the child and parse it.
            var match = e.data.match(/^responsivechild (\S+) (\d+)$/);

            // If there's no match or too many matches in the message, punt.
            if (!match || match.length !== 3) {
                return false;
            }

            // Get the ID from the message.
            var childId = match[1];

            // Is this message for me?
            if (childId != this.id) {
                return;
            }

            // Get the child's height from the message.
            var height = parseInt(match[2]);

            // Update the height.
            this.el.getElementsByTagName('iframe')[0].setAttribute('height', height + 'px');
        }

        this.sendWidthToChild = function() {
            /*
            * Transmit the current iframe width to the child.
            */

            // Get the width of the element.
            var width = this.el.offsetWidth.toString();

            // Pass the width out to the child so it can compute the height.
            this.el.getElementsByTagName('iframe')[0].contentWindow.postMessage('responsiveparent ' + this.id + ' ' + width, '*');
        }

        // Add any overrides to settings coming from config.
        for (var key in config) {
            this.settings[key] = config[key];
        }

        // Add a listener for processing messages from the child.
        var that = this;
        window.addEventListener('message', function(e) {
            return that.processChildMessage(e)
        }, false);

        // Construct the iframe in the container element.
        this.constructIframe();

        return this;
    };

    lib.Child = function(config) {
        /*
        * A global function for setting up a responsive child.
        * Use the config object to override the default settings.
        */
        this.parentWidth = null;
        this.id = null;

        this.settings = {
            renderCallback: null,
            xdomain: '*',
            polling: 0
        };

        this.getParameterByName = function(name) {
            /*
            * Generic function for parsing URL params.
            * Via http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
            */
            var regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]') + '=([^&#]*)');
            var results = regex.exec(location.search);
            return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, " "));
        };

        this.sendHeightToParent = function() {
            /*
            * Transmit the current iframe height to the parent.
            * Make this callable from external scripts in case they update the body out of sequence.
            */

            // Get the child's height.
            var height = document.getElementsByTagName('body')[0].offsetHeight.toString();

            // Send the height to the parent.
            window.top.postMessage('responsivechild ' + this.id + ' '+ height, '*');
        };

        this.processParentMessage = function(e) {
            /*
            * Process a new message from parent frame.
            */

            // First, punt if this isn't from an acceptable xdomain.
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Get the message from the parent.
            var match = e.data.match(/^responsiveparent (\S+) (\d+)$/);

            // If there's no match or it's a bad format, punt.
            if (!match || match.length !== 3) { return; }

            // Get the ID out of the message.
            var id = match[1];

            // Ensure message is meant for this child
            if (id != this.id) {
                return;
            }

            // Get the width out of the message.
            var width = parseInt(match[2]);

            // Change the width if it's different.
            if (width != this.parentWidth) {
                this.parentWidth = width;

                // Call the callback function if it exists.
                if (this.settings.renderCallback) {
                    this.settings.renderCallback(width);
                }

                // Send the height back to the parent.
                this.sendHeightToParent();
            }
        };

        // Initialize settings with overrides.
        for (var key in config) { this.settings[key] = config[key]; }

        // Set up a listener to handle any incoming messages.
        var that = this;
        window.addEventListener('message', function(e) {
            that.processParentMessage(e);
        }, false);

        // Identify what ID the parent knows this child as.
        this.id = this.getParameterByName('childId');

        // Get the initial width from a URL parameter.
        var width = parseInt(this.getParameterByName('initialWidth'));

        // If there's a callback function, call it.
        if (this.settings.renderCallback) {
            this.settings.renderCallback(width);
        }

        // Send the initial height to the parent.
        this.sendHeightToParent();

        // If we're configured to poll, create a setInterval to handle that.
        if (this.settings.polling) {
            window.setInterval(this.sendHeightToParent, this.settings.polling);
        }

        return this;
    };

    return lib;
}());
<commit_msg>removed debug statement<commit_after>/*
* Pym.js is library that resizes an iframe based on the width of the parent and the resulting height of the child.
* Check out the docs at http://foo or the readme at README.md for usage.
*/

var pym = (function() {
    var lib = {};

    var _isSafeMessage = function(e, settings) {
        /*
        * Check the message to make sure it comes from an acceptable xdomain.
        * Defaults to '*' but can be overriden in config.
        */
        if (settings.xdomain !== '*') {
            // If origin doesn't match our xdomain, return.
            if (!e.origin.match(new RegExp(settings.xdomain + '$'))) { return; }
        }

        return true;
    }

    lib.Parent = function(id, url, config) {
        /*
        * A global function for setting up a responsive parent.
        * Use the config object to override the default settings.
        */
        this.id = id;
        this.url = url;
        this.el = document.getElementById(id);

        this.settings = {
            xdomain: '*'
        };

        this.constructIframe = function() {
            /*
            * A function which handles constructing an iframe inside a given element.
            */

            // Calculate the width of this element.
            var width = this.el.offsetWidth.toString();

            // Create an iframe element attached to the document.
            var node = document.createElement("iframe");

            // Save fragment id
            var hash = '';
            var hashIndex = this.url.indexOf('#');

            if (hashIndex > -1) {
                hash = this.url.substring(hashIndex, this.url.length);
                this.url = this.url.substring(0, hashIndex);
            }

            // If the URL contains querystring bits, use them.
            // Otherwise, just create a set of valid params.
            if (this.url.indexOf('?') < 0) {
                this.url += '?';
            } else {
                this.url += '&';
            }

            // Append the initial width as a querystring parameter, and the fragment id
            node.src = this.url + 'initialWidth=' + width + '&childId=' + this.id + hash;

            // Set some attributes to this proto-iframe.
            node.setAttribute('width', '100%');
            node.setAttribute('scrolling', 'no');
            node.setAttribute('marginheight', '0');
            node.setAttribute('frameborder', '0');

            // Append the iframe to our element.
            this.el.appendChild(node);

            // Add an event listener that will handle redrawing the child on resize.
            var that = this;
            window.addEventListener('resize', function(e) {
                that.sendWidthToChild();
            });
        }

        this.processChildMessage = function(e) {
            /*
            * Process a new message from the child.
            * Used to set the height on our iframe.
            */
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Grab the message from the child and parse it.
            var match = e.data.match(/^responsivechild (\S+) (\d+)$/);

            // If there's no match or too many matches in the message, punt.
            if (!match || match.length !== 3) {
                return false;
            }

            // Get the ID from the message.
            var childId = match[1];

            // Is this message for me?
            if (childId != this.id) {
                return;
            }

            // Get the child's height from the message.
            var height = parseInt(match[2]);

            // Update the height.
            this.el.getElementsByTagName('iframe')[0].setAttribute('height', height + 'px');
        }

        this.sendWidthToChild = function() {
            /*
            * Transmit the current iframe width to the child.
            */

            // Get the width of the element.
            var width = this.el.offsetWidth.toString();

            // Pass the width out to the child so it can compute the height.
            this.el.getElementsByTagName('iframe')[0].contentWindow.postMessage('responsiveparent ' + this.id + ' ' + width, '*');
        }

        // Add any overrides to settings coming from config.
        for (var key in config) {
            this.settings[key] = config[key];
        }

        // Add a listener for processing messages from the child.
        var that = this;
        window.addEventListener('message', function(e) {
            return that.processChildMessage(e)
        }, false);

        // Construct the iframe in the container element.
        this.constructIframe();

        return this;
    };

    lib.Child = function(config) {
        /*
        * A global function for setting up a responsive child.
        * Use the config object to override the default settings.
        */
        this.parentWidth = null;
        this.id = null;

        this.settings = {
            renderCallback: null,
            xdomain: '*',
            polling: 0
        };

        this.getParameterByName = function(name) {
            /*
            * Generic function for parsing URL params.
            * Via http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
            */
            var regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]') + '=([^&#]*)');
            var results = regex.exec(location.search);
            return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, " "));
        };

        this.sendHeightToParent = function() {
            /*
            * Transmit the current iframe height to the parent.
            * Make this callable from external scripts in case they update the body out of sequence.
            */

            // Get the child's height.
            var height = document.getElementsByTagName('body')[0].offsetHeight.toString();

            // Send the height to the parent.
            window.top.postMessage('responsivechild ' + this.id + ' '+ height, '*');
        };

        this.processParentMessage = function(e) {
            /*
            * Process a new message from parent frame.
            */

            // First, punt if this isn't from an acceptable xdomain.
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Get the message from the parent.
            var match = e.data.match(/^responsiveparent (\S+) (\d+)$/);

            // If there's no match or it's a bad format, punt.
            if (!match || match.length !== 3) { return; }

            // Get the ID out of the message.
            var id = match[1];

            // Ensure message is meant for this child
            if (id != this.id) {
                return;
            }

            // Get the width out of the message.
            var width = parseInt(match[2]);

            // Change the width if it's different.
            if (width != this.parentWidth) {
                this.parentWidth = width;

                // Call the callback function if it exists.
                if (this.settings.renderCallback) {
                    this.settings.renderCallback(width);
                }

                // Send the height back to the parent.
                this.sendHeightToParent();
            }
        };

        // Initialize settings with overrides.
        for (var key in config) { this.settings[key] = config[key]; }

        // Set up a listener to handle any incoming messages.
        var that = this;
        window.addEventListener('message', function(e) {
            that.processParentMessage(e);
        }, false);

        // Identify what ID the parent knows this child as.
        this.id = this.getParameterByName('childId');

        // Get the initial width from a URL parameter.
        var width = parseInt(this.getParameterByName('initialWidth'));

        // If there's a callback function, call it.
        if (this.settings.renderCallback) {
            this.settings.renderCallback(width);
        }

        // Send the initial height to the parent.
        this.sendHeightToParent();

        // If we're configured to poll, create a setInterval to handle that.
        if (this.settings.polling) {
            window.setInterval(this.sendHeightToParent, this.settings.polling);
        }

        return this;
    };

    return lib;
}());
<|endoftext|>


<commit_before>/** @namespace

The XHR namespace provides functionality for issuing AJAX requests in a similar style
to the way jQuery does.  Why build a replacement for jQuery's ajax functionality you ask
(and a fair question, I might add)?  Basically, because I was writing a library that I
didn't want to have to rely on the presence of jQuery especially when the internals of the
way AJAX is handled changed between version 1.3.2 and 1.4.2. While not a big deal for
end users of jQuery it became a problem when you wanted to implement a replacement XHR
object.  So what does GRUNT XHR provide then?

TODO: add information here...
*/
GRUNT.XHR = (function() {
    // define some content types
    var CONTENT_TYPES = {
        HTML: "text/html",
        XML: "text/xml",
        TEXT: "text/plain",
        STREAM: "application/octet-stream"
    };

    // define some regular expressions to help determine the type of the request
    var REQUEST_URL_EXTENSIONS = {
        JSON: ['json'],
        PDON: ['pdon.txt']
    };

    var INDERMINATE_CONTENT_TYPES = ["TEXT", "STREAM"];

    // initialise some regexes
    var REGEX_URL = /^(\w+:)?\/\/([^\/?#]+)/;

    // define the variable content type processors
    var RESPONSE_TYPE_PROCESSORS = {
        XML: function(xhr, requestParams) {
            return xhr.responseXML;
        },

        JSON: function(xhr, requestParams) {
            // use the JSON object to convert the responseText to a JS object
            try {
                return JSON.parse(xhr.responseText);
            }
            catch (e) {
                GRUNT.Log.error("Error parsing JSON data: ", xhr.responseText);
                GRUNT.Log.exception(e);
            }
        },

        PDON: function(xhr, requestParams) {
            return GRUNT.Data.parse({
                data: xhr.responseText,
                format: "PDON"
            });
        },

        DEFAULT: function(xhr, requestParam) {
            return xhr.responseText;
        }
    }; // CONTENT_TYPE_PROCESSORS

    // define headers
    var HEADERS = {
        CONTENT_TYPE: "Content-Type"
    };

    /**
    This function is used to determine the appropriate request type based on the extension
    of the url that was originally requested.  This function is only called in the case where
    an indeterminate type of content-type has been received from the server that has supplied the
    response (such as application/octet-stream).

    @private
    @param {XMLHttpRequest } xhr the XMLHttpRequest object
    @param requestParams the parameters that were passed to the xhr request
    @param fallbackType the type of request that we will fallback to
    */
    function getProcessorForRequestUrl(xhr, requestParams, fallbackType) {
        for (var requestType in REQUEST_URL_EXTENSIONS) {
            // iterate through the file extensions
            for (var ii = 0; ii < REQUEST_URL_EXTENSIONS[requestType].length; ii++) {
                var fileExt = REQUEST_URL_EXTENSIONS[requestType][ii];

                // if the request url ends with the specified file extension we have a match
                if (new RegExp(fileExt + "$", "i").test(requestParams.url)) {
                    return requestType;
                } // if
            } // for
        } // for

        return fallbackType ? fallbackType : "DEFAULT";
    } // getProcessorForRequestUrl

    function processResponseData(xhr, requestParams) {
        // get the content type of the response
        var contentType = xhr.getResponseHeader(HEADERS.CONTENT_TYPE);
        var processorId;
        var matchedType = false;

        GRUNT.Log.info("processing response data, content type = " + contentType);

        // determine the matching content type
        for (processorId in CONTENT_TYPES) {
            if (contentType && (contentType.indexOf(CONTENT_TYPES[processorId]) >= 0)) {
                matchedType = true;
                break;
            }
        } // for

        // if the match type was indeterminate, then look at the url of the request to
        // determine which is the best type to match on
        var indeterminate = (! matchedType);
        for (var ii = 0; ii < INDERMINATE_CONTENT_TYPES.length; ii++) {
            indeterminate = indeterminate || (INDERMINATE_CONTENT_TYPES[ii] == processorId);
        } // for

        if (indeterminate) {
            processorId = getProcessorForRequestUrl(xhr, requestParams, processorId);
        } // if

        try {
            GRUNT.Log.info("using processor: " + processorId + " to process response");
            return RESPONSE_TYPE_PROCESSORS[processorId](xhr, requestParams);
        }
        catch (e) {
            GRUNT.Log.warn("error applying processor '" + processorId + "' to response type, falling back to default");
            return RESPONSE_TYPE_PROCESSORS.DEFAULT(xhr, requestParams);
        } // try..catch
    } // processResponseData

    // define self
    var module = GRUNT.newModule({
        id: "grunt.xhr",

        ajaxSettings: {
            xhr: null
        },

        ajax: function(params) {
            // given that I am having to write my own AJAX handling, I think it's safe to assume that I should
            // do that in the context of a try catch statement to catch the things that are going to go wrong...
            try {
                params = GRUNT.extend({
                    method: "GET",
                    data: null,
                    url: null,
                    async: true,
                    success: null,
                    contentType: "application/x-www-form-urlencoded"
                }, module.ajaxSettings, params);

                // determine if this is a remote request (as per the jQuery ajax calls)
                var parts = REGEX_URL.exec(params.url),
                    remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);

                // if we have data, then update the method to POST
                if (params.data) {
                    params.method = "POST";
                } // if

                // if the url is empty, then log an error
                if (! params.url) {
                    GRUNT.Log.warn("ajax request issued with no url - that ain't going to work...");
                    return;
                } // if

                // if the we have an xhr creator registered, then let it decide whether it wants to create the client
                var xhr = null;
                if (params.xhr) {
                    xhr = params.xhr(params);
                } // if

                // if the optional creator, didn't create the client, then create the default client
                if (! xhr) {
                    xhr = new XMLHttpRequest();
                } // if

                GRUNT.Log.info("opening request: " + JSON.stringify(params));

                // open the request
                // TODO: support basic authentication
                xhr.open(params.method, params.url, params.async);

                // if we are sending data, then set the correct content type
                if (params.data) {
                    xhr.setRequestHeader("Content-Type", params.contentType);
                } // if

                // if this is not a remote request, the set the requested with header
                if (! remote) {
                    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                } // if

                xhr.onreadystatechange = function() {
                    if (this.readyState === 4) {
                        var responseData = null;

                        try {
                            // process the response
                            responseData = processResponseData(this, params);
                        }
                        catch (e) {
                            GRUNT.Log.exception(e, "PROCESSING AJAX RESPONSE");
                        } // try..catch

                        // if the success callback is defined, then call it
                        // GRUNT.Log.info("received response, calling success handler: " + params.success);
                        if (params.success) {
                            params.success.call(this, responseData);
                        } // if
                    } // if
                }; // onreadystatechange

                // send the request
                GRUNT.Log.info("sending request with data: " + module.param(params.data));
                xhr.send(params.method == "POST" ? module.param(params.data) : null);
            }
            catch (e) {
                GRUNT.Log.exception(e);
            } // try..catch
        }, // ajax

        param: function(data) {
            // iterate through the members of the data and convert to a paramstring
            var params = [];
            var addKeyVal = function (key, value) {
                // If value is a function, invoke it and return its value
                value = GRUNT.isFunction(value) ? value() : value;
                params[ params.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            };

            // If an array was passed in, assume that it is an array of form elements.
            if (GRUNT.isArray(data)) {
                for (var ii = 0; ii < data.length; ii++) {
                    addKeyVal(data[ii].name, data[ii].value);
                } // for
            }
            else {
                for (var keyname in data) {
                    addKeyVal(keyname, data[keyname]);
                } // for
            } // if..else

            // Return the resulting serialization
            return params.join("&").replace(/%20/g, "+");
        }
    }); // self

    return module;
})();

<commit_msg>Removing some noisy logging<commit_after>/** @namespace

The XHR namespace provides functionality for issuing AJAX requests in a similar style
to the way jQuery does.  Why build a replacement for jQuery's ajax functionality you ask
(and a fair question, I might add)?  Basically, because I was writing a library that I
didn't want to have to rely on the presence of jQuery especially when the internals of the
way AJAX is handled changed between version 1.3.2 and 1.4.2. While not a big deal for
end users of jQuery it became a problem when you wanted to implement a replacement XHR
object.  So what does GRUNT XHR provide then?

TODO: add information here...
*/
GRUNT.XHR = (function() {
    // define some content types
    var CONTENT_TYPES = {
        HTML: "text/html",
        XML: "text/xml",
        TEXT: "text/plain",
        STREAM: "application/octet-stream"
    };

    // define some regular expressions to help determine the type of the request
    var REQUEST_URL_EXTENSIONS = {
        JSON: ['json'],
        PDON: ['pdon.txt']
    };

    var INDERMINATE_CONTENT_TYPES = ["TEXT", "STREAM"];

    // initialise some regexes
    var REGEX_URL = /^(\w+:)?\/\/([^\/?#]+)/;

    // define the variable content type processors
    var RESPONSE_TYPE_PROCESSORS = {
        XML: function(xhr, requestParams) {
            return xhr.responseXML;
        },

        JSON: function(xhr, requestParams) {
            // use the JSON object to convert the responseText to a JS object
            try {
                return JSON.parse(xhr.responseText);
            }
            catch (e) {
                GRUNT.Log.error("Error parsing JSON data: ", xhr.responseText);
                GRUNT.Log.exception(e);
            }
        },

        PDON: function(xhr, requestParams) {
            return GRUNT.Data.parse({
                data: xhr.responseText,
                format: "PDON"
            });
        },

        DEFAULT: function(xhr, requestParam) {
            return xhr.responseText;
        }
    }; // CONTENT_TYPE_PROCESSORS

    // define headers
    var HEADERS = {
        CONTENT_TYPE: "Content-Type"
    };

    /**
    This function is used to determine the appropriate request type based on the extension
    of the url that was originally requested.  This function is only called in the case where
    an indeterminate type of content-type has been received from the server that has supplied the
    response (such as application/octet-stream).

    @private
    @param {XMLHttpRequest } xhr the XMLHttpRequest object
    @param requestParams the parameters that were passed to the xhr request
    @param fallbackType the type of request that we will fallback to
    */
    function getProcessorForRequestUrl(xhr, requestParams, fallbackType) {
        for (var requestType in REQUEST_URL_EXTENSIONS) {
            // iterate through the file extensions
            for (var ii = 0; ii < REQUEST_URL_EXTENSIONS[requestType].length; ii++) {
                var fileExt = REQUEST_URL_EXTENSIONS[requestType][ii];

                // if the request url ends with the specified file extension we have a match
                if (new RegExp(fileExt + "$", "i").test(requestParams.url)) {
                    return requestType;
                } // if
            } // for
        } // for

        return fallbackType ? fallbackType : "DEFAULT";
    } // getProcessorForRequestUrl

    function processResponseData(xhr, requestParams) {
        // get the content type of the response
        var contentType = xhr.getResponseHeader(HEADERS.CONTENT_TYPE);
        var processorId;
        var matchedType = false;

        // GRUNT.Log.info("processing response data, content type = " + contentType);

        // determine the matching content type
        for (processorId in CONTENT_TYPES) {
            if (contentType && (contentType.indexOf(CONTENT_TYPES[processorId]) >= 0)) {
                matchedType = true;
                break;
            }
        } // for

        // if the match type was indeterminate, then look at the url of the request to
        // determine which is the best type to match on
        var indeterminate = (! matchedType);
        for (var ii = 0; ii < INDERMINATE_CONTENT_TYPES.length; ii++) {
            indeterminate = indeterminate || (INDERMINATE_CONTENT_TYPES[ii] == processorId);
        } // for

        if (indeterminate) {
            processorId = getProcessorForRequestUrl(xhr, requestParams, processorId);
        } // if

        try {
            // GRUNT.Log.info("using processor: " + processorId + " to process response");
            return RESPONSE_TYPE_PROCESSORS[processorId](xhr, requestParams);
        }
        catch (e) {
            GRUNT.Log.warn("error applying processor '" + processorId + "' to response type, falling back to default");
            return RESPONSE_TYPE_PROCESSORS.DEFAULT(xhr, requestParams);
        } // try..catch
    } // processResponseData

    // define self
    var module = GRUNT.newModule({
        id: "grunt.xhr",

        ajaxSettings: {
            xhr: null
        },

        ajax: function(params) {
            // given that I am having to write my own AJAX handling, I think it's safe to assume that I should
            // do that in the context of a try catch statement to catch the things that are going to go wrong...
            try {
                params = GRUNT.extend({
                    method: "GET",
                    data: null,
                    url: null,
                    async: true,
                    success: null,
                    contentType: "application/x-www-form-urlencoded"
                }, module.ajaxSettings, params);

                // determine if this is a remote request (as per the jQuery ajax calls)
                var parts = REGEX_URL.exec(params.url),
                    remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);

                // if we have data, then update the method to POST
                if (params.data) {
                    params.method = "POST";
                } // if

                // if the url is empty, then log an error
                if (! params.url) {
                    GRUNT.Log.warn("ajax request issued with no url - that ain't going to work...");
                    return;
                } // if

                // if the we have an xhr creator registered, then let it decide whether it wants to create the client
                var xhr = null;
                if (params.xhr) {
                    xhr = params.xhr(params);
                } // if

                // if the optional creator, didn't create the client, then create the default client
                if (! xhr) {
                    xhr = new XMLHttpRequest();
                } // if

                // GRUNT.Log.info("opening request: " + JSON.stringify(params));

                // open the request
                // TODO: support basic authentication
                xhr.open(params.method, params.url, params.async);

                // if we are sending data, then set the correct content type
                if (params.data) {
                    xhr.setRequestHeader("Content-Type", params.contentType);
                } // if

                // if this is not a remote request, the set the requested with header
                if (! remote) {
                    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
                } // if

                xhr.onreadystatechange = function() {
                    if (this.readyState === 4) {
                        var responseData = null;

                        try {
                            // process the response
                            responseData = processResponseData(this, params);
                        }
                        catch (e) {
                            GRUNT.Log.exception(e, "PROCESSING AJAX RESPONSE");
                        } // try..catch

                        // if the success callback is defined, then call it
                        // GRUNT.Log.info("received response, calling success handler: " + params.success);
                        if (params.success) {
                            params.success.call(this, responseData);
                        } // if
                    } // if
                }; // onreadystatechange

                // send the request
                // GRUNT.Log.info("sending request with data: " + module.param(params.data));
                xhr.send(params.method == "POST" ? module.param(params.data) : null);
            }
            catch (e) {
                GRUNT.Log.exception(e);
            } // try..catch
        }, // ajax

        param: function(data) {
            // iterate through the members of the data and convert to a paramstring
            var params = [];
            var addKeyVal = function (key, value) {
                // If value is a function, invoke it and return its value
                value = GRUNT.isFunction(value) ? value() : value;
                params[ params.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            };

            // If an array was passed in, assume that it is an array of form elements.
            if (GRUNT.isArray(data)) {
                for (var ii = 0; ii < data.length; ii++) {
                    addKeyVal(data[ii].name, data[ii].value);
                } // for
            }
            else {
                for (var keyname in data) {
                    addKeyVal(keyname, data[keyname]);
                } // for
            } // if..else

            // Return the resulting serialization
            return params.join("&").replace(/%20/g, "+");
        }
    }); // self

    return module;
})();

<|endoftext|>


<commit_before>
var StringUtilities = {
	getFirstInternVowel: function(word){
		vowels = word.substring(1).match(new RegExp('[AEIOU]'));
		return vowels ? vowels[0] : 'X';
	},
	getFirstInternConsonant: function(word){
		vowels = word.substring(1).match(new RegExp('[BCDFGHJKLMNPQRSTUVWXYZ]'));
		return vowels ? vowels[0] : 'X';
	},
	clearString: function(word) {

		cleanWord = word.trim();
		cleanword.replace(/\s/g,' ');
		return cleanWord.toUpperCase();
	},
	removeAccents: function(word)
	{
		accents = //todo
	}

}

var mxk = {

	getCURP: 		function(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear, bornState, gender) {

							name 	= StringUtilities.clearString(name);
							surnameFather = StringUtilities.clearString(surnameFather);
							surnameMother = StringUtilities.clearString(surnameMother);
							bornDay =		StringUtilities.clearString(bornDay);
							bornMonth =		StringUtilities.clearString(bornMonth);
							bornYear =		StringUtilities.clearString(bornYear);

							curp = this.getCommonPart(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear);
							curp += this.getGenderLetter(gender);
							curp += this.getBornStateCode(bornState);
							curp += StringUtilities.getFirstInternConsonant(surnameFather);
							curp += StringUtilities.getFirstInternConsonant(surnameMother);
							curp += StringUtilities.getFirstInternConsonant(name);

							curp += this.getSpecialChar(bornYear);

							return curp;

					},

	getCommonPart: 	function(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear) {

							commonPart = surnameFather[0];
							commonPart += StringUtilities.getFirstInternVowel(surnameFather);
							commonPart += surnameMother[0];
							commonPart += name[0];

							commonPart += bornYear.substring(2);
							commonPart += bornMonth;
							commonPart += bornDay;
							 return commonPart;
					},
	getBornStateCode: function(idState){
						return this.states[idState].code;
					},
	getGenderLetter: function(idGender){
						return idGender == 1 ? 'H' : 'M';
					},
	getSpecialChar: function(bornYear){
						if(bornYear[0] == '1') {
							return '0';
						} else {
							return 'A';
						}
					},
	removeCommonNames: function(name) {
						this.notAcceptedNames.forEach(
							function(notAccepted){
								name = name.replace(new RegExp('^' + notAccepted,g),'');
							}
							);

						return name;
					},
	states: new Array(
				{name: "AGUASCALIENTES" , code: "AS"}, //1
				{name: "BAJA CALIFORNIA" , code: "BC"},
				{name: "BAJA CALIFORNIA SUR" , code: "BS"},
				{name: "CAMPECHE" , code: "CC"},
				{name: "COAHUILA" , code: "CL"},
				{name: "COLIMA" , code: "CM"},
				{name: "CHIAPAS" , code: "CS"},
				{name: "CHIHUAHUA" , code: "CH"},
				{name: "DISTRITO FEDERAL" , code: "DF"},
				{name: "DURANGO" , code: "DG"},
				{name: "GUANAJUATO" , code: "GT"},
				{name: "GUERRERO" , code: "GR"},
				{name: "HIDALGO" , code: "HG"},
				{name: "JALISCO" , code: "JC"},
				{name: "MÉXICO" , code: "MC"},
				{name: "MICHOACÁN" , code: "MN"},
				{name: "MORELOS" , code: "MS"},
				{name: "NAYARIT" , code: "NT"},
				{name: "NUEVO LEÓN", code: "NL"},
				{name: "OAXACA" , code: "OC"},
				{name: "PUEBLA" , code: "PL"},
				{name: "QUERÉTARO" , code: "QT"},
				{name: "QUINTANA ROO" , code: "QR"},
				{name: "SAN LUIS POTOSÍ" , code: "SP"},
				{name: "SINALOA" , code: "SL"},
				{name: "SONORA" , code: "SR"},
				{name: "TABASCO" , code: "TC"},
				{name: "TAMAULIPAS" , code: "TS"},
				{name: "TLAXCALA" , code: "TL"},
				{name: "VERACRUZ" , code: "VZ"},
				{name: "YUCATÁN" , code: "YN"},
				{name: "ZACATECAS" , code: "ZS"} //32
				),
	notAcceptedNames: new Array(
		'MARIA ',
		'MARIA DE LOS '
		'JOSE ',
		'JOSÉ DE ',
		'MA. ',
		'MA ',
		'J ',
		'J. '
		)

}<commit_msg>remove accents simple, first version impplemented<commit_after>
var StringUtilities = {
	getFirstInternVowel: function(word){
		vowels = word.substring(1).match(new RegExp('[AEIOU]'));
		return vowels ? vowels[0] : 'X';
	},
	getFirstInternConsonant: function(word){
		vowels = word.substring(1).match(new RegExp('[BCDFGHJKLMNPQRSTUVWXYZ]'));
		return vowels ? vowels[0] : 'X';
	},
	clearString: function(word) {

		cleanWord = word.trim();
		cleanword.replace(/\s/g,' ');
		return cleanWord.toUpperCase();
	},
	removeAccents: function(word)
	{
		accents = {
			'Á': 'A',
			'É': 'E',
			'Í': 'I',
			'Ó': 'O',
			'Ú': 'U'
		}

		for(idx in word) {
			if (word[idx] in accents) {
				word[idx] = accents[word[idx]];
			}
		}
	}

}

var mxk = {

	getCURP: 		function(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear, bornState, gender) {

							name 	= StringUtilities.clearString(name);
							surnameFather = StringUtilities.clearString(surnameFather);
							surnameMother = StringUtilities.clearString(surnameMother);
							bornDay =		StringUtilities.clearString(bornDay);
							bornMonth =		StringUtilities.clearString(bornMonth);
							bornYear =		StringUtilities.clearString(bornYear);

							curp = this.getCommonPart(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear);
							curp += this.getGenderLetter(gender);
							curp += this.getBornStateCode(bornState);
							curp += StringUtilities.getFirstInternConsonant(surnameFather);
							curp += StringUtilities.getFirstInternConsonant(surnameMother);
							curp += StringUtilities.getFirstInternConsonant(name);

							curp += this.getSpecialChar(bornYear);

							return curp;

					},

	getCommonPart: 	function(name, surnameFather, surnameMother, bornDay, bornMonth, bornYear) {

							commonPart = surnameFather[0];
							commonPart += StringUtilities.getFirstInternVowel(surnameFather);
							commonPart += surnameMother[0];
							commonPart += name[0];

							commonPart += bornYear.substring(2);
							commonPart += bornMonth;
							commonPart += bornDay;
							 return commonPart;
					},
	getBornStateCode: function(idState){
						return this.states[idState].code;
					},
	getGenderLetter: function(idGender){
						return idGender == 1 ? 'H' : 'M';
					},
	getSpecialChar: function(bornYear){
						if(bornYear[0] == '1') {
							return '0';
						} else {
							return 'A';
						}
					},
	removeCommonNames: function(name) {
						this.notAcceptedNames.forEach(
							function(notAccepted){
								name = name.replace(new RegExp('^' + notAccepted,g),'');
							}
							);

						return name;
					},
	states: new Array(
				{name: "AGUASCALIENTES" , code: "AS"}, //1
				{name: "BAJA CALIFORNIA" , code: "BC"},
				{name: "BAJA CALIFORNIA SUR" , code: "BS"},
				{name: "CAMPECHE" , code: "CC"},
				{name: "COAHUILA" , code: "CL"},
				{name: "COLIMA" , code: "CM"},
				{name: "CHIAPAS" , code: "CS"},
				{name: "CHIHUAHUA" , code: "CH"},
				{name: "DISTRITO FEDERAL" , code: "DF"},
				{name: "DURANGO" , code: "DG"},
				{name: "GUANAJUATO" , code: "GT"},
				{name: "GUERRERO" , code: "GR"},
				{name: "HIDALGO" , code: "HG"},
				{name: "JALISCO" , code: "JC"},
				{name: "MÉXICO" , code: "MC"},
				{name: "MICHOACÁN" , code: "MN"},
				{name: "MORELOS" , code: "MS"},
				{name: "NAYARIT" , code: "NT"},
				{name: "NUEVO LEÓN", code: "NL"},
				{name: "OAXACA" , code: "OC"},
				{name: "PUEBLA" , code: "PL"},
				{name: "QUERÉTARO" , code: "QT"},
				{name: "QUINTANA ROO" , code: "QR"},
				{name: "SAN LUIS POTOSÍ" , code: "SP"},
				{name: "SINALOA" , code: "SL"},
				{name: "SONORA" , code: "SR"},
				{name: "TABASCO" , code: "TC"},
				{name: "TAMAULIPAS" , code: "TS"},
				{name: "TLAXCALA" , code: "TL"},
				{name: "VERACRUZ" , code: "VZ"},
				{name: "YUCATÁN" , code: "YN"},
				{name: "ZACATECAS" , code: "ZS"} //32
				),
	notAcceptedNames: new Array(
		'MARIA ',
		'MARIA DE LOS '
		'JOSE ',
		'JOSÉ DE ',
		'MA. ',
		'MA ',
		'J ',
		'J. '
		)

}<|endoftext|>


<commit_before>var seajs = {
  // The current version of SeaJS being used
  version: "@VERSION"
}

// Debug mode that will be turned off when building
var debugMode = "@DEBUG"

// The flag for test environment
var TEST_MODE = true

// Such code bellow will be removed when building
if (TEST_MODE) {
  var test = seajs.test = {}
}

<commit_msg>Move debugMode to config.debug<commit_after>var seajs = {
  // The current version of SeaJS being used
  version: "@VERSION"
}

// The flag for test environment
var TEST_MODE = true

// Such code bellow will be removed when building
if (TEST_MODE) {
  var test = seajs.test = {}
}

<|endoftext|>


<commit_before>function ObjectSet(){
  this._obj = {};
}

let p = ObjectSet.prototype;

p.add = function( val ){
  this._obj[ val ] = 1;
};

p.remove = function( val ){
  this._obj[ val ] = 0;
};

p.has = function( val ){
  return this._obj[ val ] === 1;
};

module.exports = typeof Set !== 'undefined' ? Set : ObjectSet;
<commit_msg>Adds forEach() to internal Set polyfill<commit_after>function ObjectSet(){
  this._obj = {};
}

let p = ObjectSet.prototype;

p.add = function( val ){
  this._obj[ val ] = 1;
};

p.remove = function( val ){
  this._obj[ val ] = 0;
};

p.has = function( val ){
  return this._obj[ val ] === 1;
};

p.forEach = function( callback, thisArg ){
  return Object.keys( this._obj ).forEach( callback, thisArg );
};

module.exports = typeof Set !== 'undefined' ? Set : ObjectSet;
<|endoftext|>


<commit_before>var fs = require('fs');
var crypto = require('crypto');
var request = require('request');
var mime = require('mime');
var GAPI = require('node-gcs').gapitoken;
var GCS = require('node-gcs');
var progress = require('progress-stream');

function _parseGcsUrl(url) {
    url = url.replace('gs://', '');
    var data = {};
    var bits = url.split('/');

    data.bucket = bits.shift();
    data.path = bits.join('/');

    return data;
}

// @todo follow 301 and 302 redirects
function _head(url, callback) {
    request.head(url, function(err, resp) {
       if (err) {
            callback(err);
            return;
        }

        if (resp.statusCode >= 400) {
            callback('Remote file is not valid');
            return;
        }

        callback(null, request(url), {size: parseInt(resp.headers['content-length'])});
    });
}

function CloudStorage(options) {
    this.options = options;

    // reformat options for gapi token module
    this.gapiOptions = {
        iss: options.accessId,
        scope: options.scope || 'https://www.googleapis.com/auth/devstorage.full_control',
        keyFile: options.privateKey
    };

    this.privateKey = null;
    this.gapi = null;
}

CloudStorage.prototype.getUrl = function(gcsUrl) {
    var data = _parseGcsUrl(gcsUrl);
    return 'http://' + data.bucket + '.storage.googleapis.com/' + data.path;
};

// @see http://stackoverflow.com/questions/20754279/creating-signed-urls-for-google-cloud-storage-using-nodejs
CloudStorage.prototype.getSignedUrl = function(gcsUrl, options) {
    var self = this;

    options = options || {};

    // default to one hour
    if (!options.hasOwnProperty('expiration')) {
        options.expiration = 3600;
    }

    var data = _parseGcsUrl(gcsUrl);

    var expiry = Math.round((new Date().getTime() / 1000) + options.expiration);
    var stringPolicy = "GET\n" + "\n" + "\n" + expiry + "\n" + '/' + data.bucket + '/' + data.path;

    // synchronous but only the first time this runs
    if (!self.privateKey) {
        self.privateKey = fs.readFileSync(self.options.privateKey, 'utf-8');
    }

    var signature = encodeURIComponent(crypto.createSign('sha256').update(stringPolicy).sign(self.privateKey, 'base64'));
    var fullUrl = (options.secure || options.ssl) ? 'https://' : 'http://';
    fullUrl += data.bucket + '.storage.googleapis.com/' + data.path + '?GoogleAccessId=' + self.options.accessId + '&Expires=' + expiry + '&Signature=' + signature;

    if (options.download) {
        var filename = options.filename || gcsUrl.split('/').pop();
        fullUrl += '&response-content-disposition=' + encodeURIComponent('attachment; filename="' + filename + '"');
    }

    return fullUrl;
};

CloudStorage.prototype.copy = function(src, destination, options, callback) {
    var self = this;

    if (callback === undefined) {
        callback = options;
        options = undefined;
    }

    callback = callback || function() {};

    if (options === undefined) {
        options = {};
    }

    // if the src looks like a url
    if (src.indexOf('//') === 0) {
        src = 'http:' + src;
    }

    function _onStat(err, path, stat) {
        if (err) {
            callback(err);
            return;
        }

        if (!self.gapi) {
            self.gapi = new GAPI(self.gapiOptions, function(err) {
                if (err) {
                    callback(err);
                    return;
                }

                _copy(path, stat);
            });
            return;
        }

        _copy(path, stat);
    }

    function _copy(path, stat) {

        var progressStream;
        if (options.onProgress) {
            progressStream = progress({
                length: stat.size,
                time: options.progressInterval || 200
            });

            progressStream.on('progress', function(progress) {
                options.onProgress.call(options, options.progressId || destination, progress);
            });
        }

        // go go go go
        var stream = path.readable ? path : fs.createReadStream(path);

        if (progressStream) {
            stream = stream.pipe(progressStream);
        }

        var headers = {
            'Content-Length': stat.size,
            'Content-Type': mime.lookup(path.href || path),
            'Cache-Control': 'public, max-age=3600, no-transform',
            'X-Goog-Acl': 'public-read'
        };

        var key;
        if (options.hasOwnProperty('headers')) {
            for (key in options.headers) {
                if (options.headers.hasOwnProperty(key)) {
                    headers[key] = options.headers[key];
                }
            }
        }

        if (options.hasOwnProperty('metadata')) {
            for (key in options.metadata) {
                if (options.metadata.hasOwnProperty(key)) {
                    headers['X-Goog-Meta-' + key] = options.metadata[key];
                }
            }
        }

        var destinationData = _parseGcsUrl(destination);

        var gcs = new GCS(self.gapi);
        gcs.putStream(stream, destinationData.bucket, '/' + destinationData.path, headers, function(err, res, body) {
            if (err) {
                callback(err, res, body);
                return;
            }

            if (res.statusCode >= 400) {
                callback(body);
                return;
            }

            var isPublic = headers['X-Goog-Acl'].indexOf('public-') === 0;

            if (options.removeAfterCopy && !path.readable) {
                fs.unlink(path, function() {
                    callback(null, isPublic ? self.getUrl(destination) : self.getSignedUrl(destination));
                });
                return;
            }

            callback(null, isPublic ? self.getUrl(destination) : self.getSignedUrl(destination));
        });
    }

    if (/^https?:\/\//.test(src)) {
        _head(src, _onStat);
        return;
    }

    fs.stat(src, function(err, stat) {
        _onStat(err, src, stat);
    });
};

CloudStorage.prototype.remove = function(path, callback) {
    var self = this;

    callback = callback || function() {};

    function _remove(path) {
        var gcs = new GCS(self.gapi);
        var data = _parseGcsUrl(path);

        gcs.deleteFile(data.bucket, '/' + data.path, function(err, resp, body) {
            if (err) {
                callback(err, false);
                return;
            }

            if (resp.statusCode >= 400) {
                callback(body, false);
                return;
            }

            callback(null, true);
        });
    }

    if (!self.gapi) {
        self.gapi = new GAPI(self.gapiOptions, function(err) {
            if (err) {
                callback(err, false);
                return;
            }

            _remove(path);
        });
        return;
    }

    _remove(path);
};

module.exports = CloudStorage;
<commit_msg>Add force extension option<commit_after>var fs = require('fs');
var crypto = require('crypto');
var request = require('request');
var mime = require('mime');
var GAPI = require('node-gcs').gapitoken;
var GCS = require('node-gcs');
var progress = require('progress-stream');

function _parseGcsUrl(url) {
    url = url.replace('gs://', '');
    var data = {};
    var bits = url.split('/');

    data.bucket = bits.shift();
    data.path = bits.join('/');

    return data;
}

// @todo follow 301 and 302 redirects
function _head(url, callback) {
    request.head(url, function(err, resp) {
       if (err) {
            callback(err);
            return;
        }

        if (resp.statusCode >= 400) {
            callback('Remote file is not valid');
            return;
        }

        callback(null, request(url), {size: parseInt(resp.headers['content-length'])});
    });
}

function CloudStorage(options) {
    this.options = options;

    // reformat options for gapi token module
    this.gapiOptions = {
        iss: options.accessId,
        scope: options.scope || 'https://www.googleapis.com/auth/devstorage.full_control',
        keyFile: options.privateKey
    };

    this.privateKey = null;
    this.gapi = null;
}

CloudStorage.prototype.getUrl = function(gcsUrl) {
    var data = _parseGcsUrl(gcsUrl);
    return 'http://' + data.bucket + '.storage.googleapis.com/' + data.path;
};

// @see http://stackoverflow.com/questions/20754279/creating-signed-urls-for-google-cloud-storage-using-nodejs
CloudStorage.prototype.getSignedUrl = function(gcsUrl, options) {
    var self = this;

    options = options || {};

    // default to one hour
    if (!options.hasOwnProperty('expiration')) {
        options.expiration = 3600;
    }

    var data = _parseGcsUrl(gcsUrl);

    var expiry = Math.round((new Date().getTime() / 1000) + options.expiration);
    var stringPolicy = "GET\n" + "\n" + "\n" + expiry + "\n" + '/' + data.bucket + '/' + data.path;

    // synchronous but only the first time this runs
    if (!self.privateKey) {
        self.privateKey = fs.readFileSync(self.options.privateKey, 'utf-8');
    }

    var signature = encodeURIComponent(crypto.createSign('sha256').update(stringPolicy).sign(self.privateKey, 'base64'));
    var fullUrl = (options.secure || options.ssl) ? 'https://' : 'http://';
    fullUrl += data.bucket + '.storage.googleapis.com/' + data.path + '?GoogleAccessId=' + self.options.accessId + '&Expires=' + expiry + '&Signature=' + signature;

    if (options.download) {
        var filename = options.filename || gcsUrl.split('/').pop();
        fullUrl += '&response-content-disposition=' + encodeURIComponent('attachment; filename="' + filename + '"');
    }

    return fullUrl;
};

CloudStorage.prototype.copy = function(src, destination, options, callback) {
    var self = this;

    if (callback === undefined) {
        callback = options;
        options = undefined;
    }

    callback = callback || function() {};

    if (options === undefined) {
        options = {};
    }

    // if the src looks like a url
    if (src.indexOf('//') === 0) {
        src = 'http:' + src;
    }

    function _onStat(err, path, stat) {
        if (err) {
            callback(err);
            return;
        }

        if (!self.gapi) {
            self.gapi = new GAPI(self.gapiOptions, function(err) {
                if (err) {
                    callback(err);
                    return;
                }

                _copy(path, stat);
            });
            return;
        }

        _copy(path, stat);
    }

    function _copy(path, stat) {

        var progressStream;
        if (options.onProgress) {
            progressStream = progress({
                length: stat.size,
                time: options.progressInterval || 200
            });

            progressStream.on('progress', function(progress) {
                options.onProgress.call(options, options.progressId || destination, progress);
            });
        }

        // go go go go
        var stream = path.readable ? path : fs.createReadStream(path);

        if (progressStream) {
            stream = stream.pipe(progressStream);
        }

        var headers = {
            'Content-Length': stat.size,
            'Content-Type': mime.lookup(path.href || path),
            'Cache-Control': 'public, max-age=3600, no-transform',
            'X-Goog-Acl': 'public-read'
        };

        // missing extension on destination
        // use the source or the content type
        if (options.forceExtension && destination.split('/').pop().split('.').length === 1) {
            var fileName = (path.href || path).split('/').pop();
            var extension = fileName.indexOf('.') ? fileName.split('.').pop() : mime.extension(headers['Content-Type']);
            destination += '.' + extension;
        }

        var key;
        if (options.hasOwnProperty('headers')) {
            for (key in options.headers) {
                if (options.headers.hasOwnProperty(key)) {
                    headers[key] = options.headers[key];
                }
            }
        }

        if (options.hasOwnProperty('metadata')) {
            for (key in options.metadata) {
                if (options.metadata.hasOwnProperty(key)) {
                    headers['X-Goog-Meta-' + key] = options.metadata[key];
                }
            }
        }

        var destinationData = _parseGcsUrl(destination);

        var gcs = new GCS(self.gapi);
        gcs.putStream(stream, destinationData.bucket, '/' + destinationData.path, headers, function(err, res, body) {
            if (err) {
                callback(err, res, body);
                return;
            }

            if (res.statusCode >= 400) {
                callback(body);
                return;
            }

            var isPublic = headers['X-Goog-Acl'].indexOf('public-') === 0;

            if (options.removeAfterCopy && !path.readable) {
                fs.unlink(path, function() {
                    callback(null, isPublic ? self.getUrl(destination) : self.getSignedUrl(destination));
                });
                return;
            }

            callback(null, isPublic ? self.getUrl(destination) : self.getSignedUrl(destination));
        });
    }

    if (/^https?:\/\//.test(src)) {
        _head(src, _onStat);
        return;
    }

    fs.stat(src, function(err, stat) {
        _onStat(err, src, stat);
    });
};

CloudStorage.prototype.remove = function(path, callback) {
    var self = this;

    callback = callback || function() {};

    function _remove(path) {
        var gcs = new GCS(self.gapi);
        var data = _parseGcsUrl(path);

        gcs.deleteFile(data.bucket, '/' + data.path, function(err, resp, body) {
            if (err) {
                callback(err, false);
                return;
            }

            if (resp.statusCode >= 400) {
                callback(body, false);
                return;
            }

            callback(null, true);
        });
    }

    if (!self.gapi) {
        self.gapi = new GAPI(self.gapiOptions, function(err) {
            if (err) {
                callback(err, false);
                return;
            }

            _remove(path);
        });
        return;
    }

    _remove(path);
};

module.exports = CloudStorage;
<|endoftext|>