whole_func_string: function ial(app, opts) {
  
    /**
     * Lazily creates an i18n.
     *
     * @api public
     */
  
    Object.defineProperty(app.context, 'i18n', {
      get: function () {
        if (this._i18n) {
          return this._i18n
        }
  
        const i18n = new I18n(opts)
        i18n.request = this.request
        this._i18n = i18n
  
        // merge into ctx.state
        this.state.i18n = i18n
        registerMethods(this.state, i18n)
  
        debug('app.ctx.i18n %j', i18n)
        return i18n
      }
    })
  
    Object.defineProperty(app.request, 'i18n', {
      get: function () {
        return this.ctx.i18n
      }
    })
  
    return function i18nMiddleware(ctx, next) {
      ctx.i18n.whitelist.some(key => {
        const customLocaleMethod = typeof key === 'function'
          && ctx.i18n.setLocale(key.apply(ctx))
        if (customLocaleMethod || ctx.i18n[SET_PREFIX + key]()) return true
      })
      return next()
    }
  }
func_code_string: function ial(app, opts) {
  
    /**
     * Lazily creates an i18n.
     *
     * @api public
     */
  
    Object.defineProperty(app.context, 'i18n', {
      get: function () {
        if (this._i18n) {
          return this._i18n
        }
  
        const i18n = new I18n(opts)
        i18n.request = this.request
        this._i18n = i18n
  
        // merge into ctx.state
        this.state.i18n = i18n
        registerMethods(this.state, i18n)
  
        debug('app.ctx.i18n %j', i18n)
        return i18n
      }
    })
  
    Object.defineProperty(app.request, 'i18n', {
      get: function () {
        return this.ctx.i18n
      }
    })
  
    return function i18nMiddleware(ctx, next) {
      ctx.i18n.whitelist.some(key => {
        const customLocaleMethod = typeof key === 'function'
          && ctx.i18n.setLocale(key.apply(ctx))
        if (customLocaleMethod || ctx.i18n[SET_PREFIX + key]()) return true
      })
      return next()
    }
  }
func_documentation_string: Internationalization and Localization