text: var responseDisplay = 'data'
  var coreapi = window.coreapi
  var schema = window.schema
  
  function normalizeKeys (arr) {
    var _normarr = [];
    for (var i = 0; i < arr.length; i++) {
      _normarr = _normarr.concat(arr[i].split(' > '));
    }
    return _normarr;
  }
  
  function normalizeHTTPHeader (str) {
    // Capitalize HTTP headers for display.
    return (str.charAt(0).toUpperCase() + str.substring(1))
      .replace(/-(.)/g, function ($1) {
        return $1.toUpperCase()
      })
      .replace(/(Www)/g, function ($1) {
        return 'WWW'
      })
      .replace(/(Xss)/g, function ($1) {
        return 'XSS'
      })
      .replace(/(Md5)/g, function ($1) {
        return 'MD5'
      })
  }
  
  function formEntries (form) {
    // Polyfill for new FormData(form).entries()
    var formData = new FormData(form)
    if (formData.entries !== undefined) {
      return Array.from(formData.entries())
    }
  
    var entries = []
  
    for (var i = 0; i < form.elements.length; i++) {
      var element = form.elements[i]
  
      if (!element.name) {
        continue
      }
  
      if (element.type === 'file') {
        for (var j = 0; j < element.files.length; j++) {
          entries.push([element.name, element.files[j]])
        }
      } else if (element.type === 'select-multiple' || element.type === 'select-one') {
        for (var j = 0; j < element.selectedOptions.length; j++) {
          entries.push([element.name, element.selectedOptions[j].value])
        }
      } else if (element.type === 'checkbox') {
        if (element.checked) {
          entries.push([element.name, element.value])
        }
      } else {
        entries.push([element.name, element.value])
      }
    }
  
    return entries
  }
  
  $(function () {
    var $selectedAuthentication = $('#selected-authentication')
    var $authControl = $('#auth-control')
    var $authTokenModal = $('#auth_token_modal')
    var $authBasicModal = $('#auth_basic_modal')
    var $authSessionModal = $('#auth_session_modal')
  
    // Language Control
    $('#language-control li').click(function (event) {
      event.preventDefault()
      var $languageMenuItem = $(this).find('a')
      var $languageControls = $(this).closest('ul').find('li')
      var $languageControlLinks = $languageControls.find('a')
      var language = $languageMenuItem.data('language')
  
      $languageControlLinks.not('[data-language="' + language + '"]').parent().removeClass('active')
      $languageControlLinks.filter('[data-language="' + language + '"]').parent().addClass('active')
  
      $('#selected-language').text(language)
  
      var $codeBlocks = $('pre.highlight')
      $codeBlocks.not('[data-language="' + language + '"]').addClass('hide')
      $codeBlocks.filter('[data-language="' + language + '"]').removeClass('hide')
    })
  
    // API Explorer
    $('form.api-interaction').submit(function (event) {
      event.preventDefault()
  
      var $form = $(this).closest('form')
      var $requestMethod = $form.find('.request-method')
      var $requestUrl = $form.find('.request-url')
      var $toggleView = $form.closest('.modal-content').find('.toggle-view')
      var $responseStatusCode = $form.find('.response-status-code')
      var $meta = $form.find('.meta')
      var $responseRawResponse = $form.find('.response-raw-response')
      var $requestAwaiting = $form.find('.request-awaiting')
      var $responseRaw = $form.find('.response-raw')
      var $responseData = $form.find('.response-data')
      var key = normalizeKeys($form.data('key'))
      var params = {}
      var entries = formEntries($form.get()[0])
  
      for (var i = 0; i < entries.length; i++) {
        var entry = entries[i]
        var paramKey = entry[0]
        var paramValue = entry[1]
        var $elem = $form.find('[name="' + paramKey + '"]')
        var dataType = $elem.data('type') || 'string'
  
        if (dataType === 'integer' && paramValue) {
          var value = parseInt(paramValue)
          if (!isNaN(value)) {
            params[paramKey] = value
          }
        } else if (dataType === 'number' && paramValue) {
          var value = parseFloat(paramValue)
          if (!isNaN(value)) {
            params[paramKey] = value
          }
        } else if (dataType === 'boolean' && paramValue) {
          var value = {
            'true': true,
            'false': false
          }[paramValue.toLowerCase()]
          if (value !== undefined) {
            params[paramKey]
          }
        } else if (dataType === 'array' && paramValue) {
          try {
            params[paramKey] = JSON.parse(paramValue)
          } catch (err) {
            // Ignore malformed JSON
          }
        } else if (dataType === 'object' && paramValue) {
          try {
            params[paramKey] = JSON.parse(paramValue)
          } catch (err) {
            // Ignore malformed JSON
          }
        } else if (dataType === 'string' && paramValue) {
          params[paramKey] = paramValue
        }
      }
  
      $form.find(':checkbox').each(function (index) {
        // Handle unselected checkboxes
        var name = $(this).attr('name')
        if (!params.hasOwnProperty(name)) {
          params[name] = false
        }
      })
  
      function requestCallback (request) {
        // Fill in the "GET /foo/" display.
        var parser = document.createElement('a')
        parser.href = request.url
        var method = request.options.method
        var path = parser.pathname + parser.hash + parser.search
  
        $requestMethod.text(method)
        $requestUrl.text(path)
      }
  
      function responseCallback (response, responseText) {
        // Display the 'Data'/'Raw' control.
        $toggleView.removeClass('hide')
  
        // Fill in the "200 OK" display.
        $responseStatusCode.removeClass('label-success').removeClass('label-danger')
        if (response.ok) {
          $responseStatusCode.addClass('label-success')
        } else {
          $responseStatusCode.addClass('label-danger')
        }
        $responseStatusCode.text(response.status)
        $meta.removeClass('hide')
  
        // Fill in the Raw HTTP response display.
        var panelText = 'HTTP/1.1 ' + response.status + ' ' + response.statusText + '\n'
        response.headers.forEach(function (header, key) {
          panelText += normalizeHTTPHeader(key) + ': ' + header + '\n'
        })
        if (responseText) {
          panelText += '\n' + responseText
        }
        $responseRawResponse.text(panelText)
      }
  
      // Instantiate a client to make the outgoing request.
      var options = {
        requestCallback: requestCallback,
        responseCallback: responseCallback
      }
  
      // Setup authentication options.
      if (window.auth && window.auth.type === 'token') {
        // Header authentication
        options.auth = new coreapi.auth.TokenAuthentication({
          scheme: window.auth.scheme,
          token: window.auth.token
        })
      } else if (window.auth && window.auth.type === 'basic') {
        // Basic authentication
        options.auth = new coreapi.auth.BasicAuthentication({
          username: window.auth.username,
          password: window.auth.password
        })
      } else if (window.auth && window.auth.type === 'session') {
        // Session authentication
        options.auth = new coreapi.auth.SessionAuthentication({
          csrfCookieName: 'csrftoken',
          csrfHeaderName: 'X-CSRFToken'
        })
      }
  
      var client = new coreapi.Client(options)
      client.action(schema, key, params).then(function (data) {
        var response = JSON.stringify(data, null, 2)
        $requestAwaiting.addClass('hide')
        $responseRaw.addClass('hide')
        $responseData.addClass('hide').text('').jsonView(response)
  
        if (responseDisplay === 'data') {
          $responseData.removeClass('hide')
        } else {
          $responseRaw.removeClass('hide')
        }
      }).catch(function (error) {
        var response = JSON.stringify(error.content, null, 2)
        $requestAwaiting.addClass('hide')
        $responseRaw.addClass('hide')
        $responseData.addClass('hide').text('').jsonView(response)
  
        if (responseDisplay === 'data') {
          $responseData.removeClass('hide')
        } else {
          $responseRaw.removeClass('hide')
        }
      })
    })
  
    // 'Data'/'Raw' control
    $('.toggle-view button').click(function () {
      var $modalContent = $(this).closest('.modal-content')
      var $modalResponseRaw = $modalContent.find('.response-raw')
      var $modalResponseData = $modalContent.find('.response-data')
  
      responseDisplay = $(this).data('display-toggle')
  
      $(this).removeClass('btn-default').addClass('btn-info').siblings().removeClass('btn-info')
  
      if (responseDisplay === 'raw') {
        $modalResponseRaw.removeClass('hide')
        $modalResponseData.addClass('hide')
      } else {
        $modalResponseData.removeClass('hide')
        $modalResponseRaw.addClass('hide')
      }
    })
  
    // Authentication: none
    $authControl.find("[data-auth='none']").click(function (event) {
      event.preventDefault()
      window.auth = null
      $selectedAuthentication.text('none')
      $authControl.find("[data-auth]").closest('li').removeClass('active')
      $authControl.find("[data-auth='none']").closest('li').addClass('active')
    })
  
    // Authentication: token
    $('form.authentication-token-form').submit(function (event) {
      event.preventDefault()
      var $form = $(this).closest('form')
      var scheme = $form.find('input#scheme').val()
      var token = $form.find('input#token').val()
      window.auth = {
        'type': 'token',
        'scheme': scheme,
        'token': token
      }
      $selectedAuthentication.text('token')
      $authControl.find("[data-auth]").closest('li').removeClass('active')
      $authControl.find("[data-auth='token']").closest('li').addClass('active')
      $authTokenModal.modal('hide')
    })
  
    // Authentication: basic
    $('form.authentication-basic-form').submit(function (event) {
      event.preventDefault()
      var $form = $(this).closest('form')
      var username = $form.find('input#username').val()
      var password = $form.find('input#password').val()
      window.auth = {
        'type': 'basic',
        'username': username,
        'password': password
      }
      $selectedAuthentication.text('basic')
      $authControl.find("[data-auth]").closest('li').removeClass('active')
      $authControl.find("[data-auth='basic']").closest('li').addClass('active')
      $authBasicModal.modal('hide')
    })
  
    // Authentication: session
    $('form.authentication-session-form').submit(function (event) {
      event.preventDefault()
      window.auth = {
        'type': 'session'
      }
      $selectedAuthentication.text('session')
      $authControl.find("[data-auth]").closest('li').removeClass('active')
      $authControl.find("[data-auth='session']").closest('li').addClass('active')
      $authSessionModal.modal('hide')
    })
  })
  