HEX
Server: LiteSpeed
System: Linux linux31.centraldnserver.com 4.18.0-553.83.1.lve.el8.x86_64 #1 SMP Wed Nov 12 10:04:12 UTC 2025 x86_64
User: salamatk (1501)
PHP: 8.1.33
Disabled: show_source, system, shell_exec, passthru, exec, popen, proc_open
Upload Files
File: /home/salamatk/takarzan.ir/wp-content/themes/xts-luman/js/jquery.pjax.js
/*!
 * Copyright 2012, Chris Wanstrath
 * Released under the MIT License
 * https://github.com/defunkt/jquery-pjax
 */

(function($){

  // When called on a container with a selector, fetches the href with
  // ajax into the container or with the data-pjax attribute on the link
  // itself.
  //
  // Tries to make sure the back button and ctrl+click work the way
  // you'd expect.
  //
  // Exported as $.fn.pjax
  //
  // Accepts a jQuery ajax options object that may include these
  // pjax specific options:
  //
  //
  // container - Where to stick the response body. Usually a String selector.
  //             $(container).html(xhr.responseBody)
  //             (default: current jquery context)
  //      push - Whether to pushState the URL. Defaults to true (of course).
  //   replace - Want to use replaceState instead? That's cool.
  //
  // For convenience the second parameter can be either the container or
  // the options object.
  //
  // Returns the jQuery object
  function fnPjax(selector, container, options) {
    var context = this
    return this.on('click.pjax', selector, function(event) {
      var opts = $.extend({}, optionsFor(container, options))
      if (!opts.container)
        opts.container = $(this).attr('data-pjax') || context
      handleClick(event, opts)
    })
  }

  // Public: pjax on click handler
  //
  // Exported as $.pjax.click.
  //
  // event   - "click" jQuery.Event
  // options - pjax options
  //
  // Examples
  //
  //   $(document).on('click', 'a', $.pjax.click)
  //   // is the same as
  //   $(document).pjax('a')
  //
  //  $(document).on('click', 'a', function(event) {
  //    var container = $(this).closest('[data-pjax-container]')
  //    $.pjax.click(event, container)
  //  })
  //
  // Returns nothing.
  function handleClick(event, container, options) {
    options = optionsFor(container, options)

    var link = event.currentTarget

    if (link.tagName.toUpperCase() !== 'A')
      throw "$.fn.pjax or $.pjax.click requires an anchor element"

    // Middle click, cmd click, and ctrl click should open
    // links in a new tab as normal.
    if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
      return

    // Ignore cross origin links
    if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
      return

    // Ignore case when a hash is being tacked on the current URL
    if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
      return

    // Ignore event with default prevented
    if (event.isDefaultPrevented())
      return

    var defaults = {
      url: link.href,
      container: $(link).attr('data-pjax'),
      target: link
    }

    var opts = $.extend({}, defaults, options)
    var clickEvent = $.Event('pjax:click')
    $(link).trigger(clickEvent, [opts])

    if (!clickEvent.isDefaultPrevented()) {
      pjax(opts)
      event.preventDefault()
      $(link).trigger('pjax:clicked', [opts])
    }
  }

  // Public: pjax on form submit handler
  //
  // Exported as $.pjax.submit
  //
  // event   - "click" jQuery.Event
  // options - pjax options
  //
  // Examples
  //
  //  $(document).on('submit', 'form', function(event) {
  //    var container = $(this).closest('[data-pjax-container]')
  //    $.pjax.submit(event, container)
  //  })
  //
  // Returns nothing.
  function handleSubmit(event, container, options) {
    options = optionsFor(container, options)

    var form = event.currentTarget
    var $form = $(form)

    if (form.tagName.toUpperCase() !== 'FORM')
      throw "$.pjax.submit requires a form element"

    var defaults = {
      type: ($form.attr('method') || 'GET').toUpperCase(),
      url: $form.attr('action'),
      container: $form.attr('data-pjax'),
      target: form
    }

    if (defaults.type !== 'GET' && window.FormData !== undefined) {
      defaults.data = new FormData(form);
      defaults.processData = false;
      defaults.contentType = false;
    } else {
      // Can't handle file uploads, exit
      if ($(form).find(':file').length) {
        return;
      }

      // Fallback to manually serializing the fields
      defaults.data = $(form).serializeArray();
    }

    pjax($.extend({}, defaults, options))

    event.preventDefault()
  }

  // Loads a URL with ajax, puts the response body inside a container,
  // then pushState()'s the loaded URL.
  //
  // Works just like $.ajax in that it accepts a jQuery ajax
  // settings object (with keys like url, type, data, etc).
  //
  // Accepts these extra keys:
  //
  // container - Where to stick the response body.
  //             $(container).html(xhr.responseBody)
  //      push - Whether to pushState the URL. Defaults to true (of course).
  //   replace - Want to use replaceState instead? That's cool.
  //
  // Use it just like $.ajax:
  //
  //   var xhr = $.pjax({ url: this.href, container: '#main' })
  //   console.log( xhr.readyState )
  //
  // Returns whatever $.ajax returns.
  function pjax(options) {
    options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)

    if (typeof options.url === 'function') {
      options.url = options.url()
    }

    var target = options.target

    var hash = parseURL(options.url).hash

    var _container = findContainerFor(options.container)
    var context = options.context = _container[0]
    var selector = _container[1]

    // We want the browser to maintain two separate internal caches: one
    // for pjax'd partial page loads and one for normal page loads.
    // Without adding this secret parameter, some browsers will often
    // confuse the two.
    if (!options.data) options.data = {}
    if (Array.isArray(options.data)) {
      options.data.push({name: '_pjax', value: selector})
    } else {
      options.data._pjax = selector
    }

    function fire(type, args, props) {
      if (!props) props = {}
      props.relatedTarget = target
      var event = $.Event(type, props)
      context.trigger(event, args)
      return !event.isDefaultPrevented()
    }

    var timeoutTimer

    options.beforeSend = function(xhr, settings) {
      // No timeout for non-GET requests
      // Its not safe to request the resource again with a fallback method.
      if (settings.type !== 'GET') {
        settings.timeout = 0
      }

      xhr.setRequestHeader('X-PJAX', 'true')
      xhr.setRequestHeader('X-PJAX-Container', selector)

      if (!fire('pjax:beforeSend', [xhr, settings]))
        return false

      if (settings.timeout > 0) {
        timeoutTimer = setTimeout(function() {
          if (fire('pjax:timeout', [xhr, options]))
            xhr.abort('timeout')
        }, settings.timeout)

        // Clear timeout setting so jquerys internal timeout isn't invoked
        settings.timeout = 0
      }

      var url = parseURL(settings.url)
      if (hash) url.hash = hash
      options.requestUrl = stripInternalParams(url)
    }

    options.complete = function(xhr, textStatus) {
      if (timeoutTimer)
        clearTimeout(timeoutTimer)

      fire('pjax:complete', [xhr, textStatus, options])

      fire('pjax:end', [xhr, options])
    }

    options.error = function(xhr, textStatus, errorThrown) {
      var container = extractContainer("", xhr, options)

      var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
      if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
        locationReplace(container.url)
      }
    }

    options.success = function(data, status, xhr) {
      var previousState = pjax.state;

      // If $.pjax.defaults.version is a function, invoke it first.
      // Otherwise it can be a static string.
      var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
          $.pjax.defaults.version() :
          $.pjax.defaults.version

      var latestVersion = xhr.getResponseHeader('X-PJAX-Version')

      var container = extractContainer(data, xhr, options)

      var url = parseURL(container.url)
      if (hash) {
        url.hash = hash
        container.url = url.href
      }

      // If there is a layout version mismatch, hard load the new url
      if (currentVersion && latestVersion && currentVersion !== latestVersion) {
        locationReplace(container.url)
        return
      }

      // If the new response is missing a body, hard load the page
      if (!container.contents) {
        locationReplace(container.url)
        return
      }

      pjax.state = {
        id: options.id || uniqueId(),
        url: container.url,
        title: container.title,
        container: selector,
        fragment: options.fragment,
        timeout: options.timeout
      }

      if (options.push || options.replace) {
        window.history.replaceState(pjax.state, container.title, container.url)
      }

      // Only blur the focus if the focused element is within the container.
      var blurFocus = $.contains(options.container, document.activeElement)

      // Clear out any focused controls before inserting new page contents.
      if (blurFocus) {
        try {
          document.activeElement.blur()
        } catch (e) { }
      }

      if (container.title) document.title = container.title

      fire('pjax:beforeReplace', [container.contents, options], {
        state: pjax.state,
        previousState: previousState
      })
      context.html(container.contents)

      // FF bug: Won't autofocus fields that are inserted via JS.
      // This behavior is incorrect. So if theres no current focus, autofocus
      // the last field.
      //
      // http://www.w3.org/html/wg/drafts/html/master/forms.html
      var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
      if (autofocusEl && document.activeElement !== autofocusEl) {
        autofocusEl.focus();
      }

      executeScriptTags(container.scripts)

      var scrollTo = options.scrollTo

      // Ensure browser scrolls to the element referenced by the URL anchor
      if (hash) {
        var name = decodeURIComponent(hash.slice(1))
        var target = document.getElementById(name) || document.getElementsByName(name)[0]
        if (target) scrollTo = $(target).offset().top
      }

      if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)

      fire('pjax:success', [data, status, xhr, options])
    }


    // Initialize pjax.state for the initial page load. Assume we're
    // using the container and options of the link we're loading for the
    // back button to the initial page. This ensures good back button
    // behavior.
    if (!pjax.state) {
      pjax.state = {
        id: uniqueId(),
        url: window.location.href,
        title: document.title,
        container: selector,
        fragment: options.fragment,
        timeout: options.timeout
      }
      window.history.replaceState(pjax.state, document.title)
    }

    // Cancel the current request if we're already pjaxing
    abortXHR(pjax.xhr)

    pjax.options = options
    var xhr = pjax.xhr = $.ajax(options)

    if (xhr.readyState > 0) {
      if (options.push && !options.replace) {
        // Cache current container element before replacing it
        cachePush(pjax.state.id, cloneContents(context, selector))

        window.history.pushState(null, "", options.requestUrl)
      }

      fire('pjax:start', [xhr, options])
      fire('pjax:send', [xhr, options])
    }

    return pjax.xhr
  }

  // Public: Reload current page with pjax.
  //
  // Returns whatever $.pjax returns.
  function pjaxReload(container, options) {
    var defaults = {
      url: window.location.href,
      push: false,
      replace: true,
      scrollTo: false
    }

    return pjax($.extend(defaults, optionsFor(container, options)))
  }

  // Internal: Hard replace current state with url.
  //
  // Work for around WebKit
  //   https://bugs.webkit.org/show_bug.cgi?id=93506
  //
  // Returns nothing.
  function locationReplace(url) {
    window.history.replaceState(null, "", pjax.state.url)
    window.location.replace(url)
  }


  var initialPop = true
  var initialURL = window.location.href
  var initialState = window.history.state

  // Initialize $.pjax.state if possible
  // Happens when reloading a page and coming forward from a different
  // session history.
  if (initialState && initialState.container) {
    pjax.state = initialState
  }

  // Non-webkit browsers don't fire an initial popstate event
  if ('state' in window.history) {
    initialPop = false
  }

  // popstate handler takes care of the back and forward buttons
  //
  // You probably shouldn't use pjax on pages with other pushState
  // stuff yet.
  function onPjaxPopstate(event) {

    // Hitting back or forward should override any pending PJAX request.
    if (!initialPop) {
      abortXHR(pjax.xhr)
    }

    var previousState = pjax.state
    var state = event.state
    var direction

    if (state && state.container) {
      // When coming forward from a separate history session, will get an
      // initial pop with a state we are already at. Skip reloading the current
      // page.
      if (initialPop && initialURL == state.url) return

      if (previousState) {
        // If popping back to the same state, just skip.
        // Could be clicking back from hashchange rather than a pushState.
        if (previousState.id === state.id) return

        // Since state IDs always increase, we can deduce the navigation direction
        direction = previousState.id < state.id ? 'forward' : 'back'
      }

      var cache = cacheMapping[state.id] || []
      var selector = cache[0] || state.container
      var container = $(selector), contents = cache[1]

      if (container.length) {
        if (previousState) {
          // Cache current container before replacement and inform the
          // cache which direction the history shifted.
          cachePop(direction, previousState.id, cloneContents(container, selector))
        }

        var popstateEvent = $.Event('pjax:popstate', {
          state: state,
          direction: direction
        })
        container.trigger(popstateEvent)

        var options = {
          id: state.id,
          url: state.url,
          container: container,
          push: false,
          fragment: state.fragment,
          timeout: state.timeout,
          scrollTo: false
        }

        if (contents) {
          container.trigger('pjax:start', [null, options])

          pjax.state = state
          if (state.title) document.title = state.title
          var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
            state: state,
            previousState: previousState
          })
          container.trigger(beforeReplaceEvent, [contents, options])
          container.html(contents)

          container.trigger('pjax:end', [null, options])
        } else {
          pjax(options)
        }

        // Force reflow/relayout before the browser tries to restore the
        // scroll position.
        container[0].offsetHeight
      } else {
        locationReplace(location.href)
      }
    }
    initialPop = false
  }

  // Fallback version of main pjax function for browsers that don't
  // support pushState.
  //
  // Returns nothing since it retriggers a hard form submission.
  function fallbackPjax(options) {
    var url = typeof options.url === 'function' ? options.url() : options.url,
        method = options.type ? options.type.toUpperCase() : 'GET'

    var form = $('<form>', {
      method: method === 'GET' ? 'GET' : 'POST',
      action: url,
      style: 'display:none'
    })

    if (method !== 'GET' && method !== 'POST') {
      form.append($('<input>', {
        type: 'hidden',
        name: '_method',
        value: method.toLowerCase()
      }))
    }

    var data = options.data
    if (typeof data === 'string') {
      $.each(data.split('&'), function(index, value) {
        var pair = value.split('=')
        form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
      })
    } else if (Array.isArray(data)) {
      $.each(data, function(index, value) {
        form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
      })
    } else if (typeof data === 'object') {
      var key
      for (key in data)
        form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
    }

    $(document.body).append(form)
    form.trigger('submit')
  }

  // Internal: Abort an XmlHttpRequest if it hasn't been completed,
  // also removing its event handlers.
  function abortXHR(xhr) {
    if ( xhr && xhr.readyState < 4) {
      xhr.onreadystatechange = $.noop
      xhr.abort()
    }
  }

  // Internal: Generate unique id for state object.
  //
  // Use a timestamp instead of a counter since ids should still be
  // unique across page loads.
  //
  // Returns Number.
  function uniqueId() {
    return (new Date).getTime()
  }

  function cloneContents(container, selector) {
    var cloned = container.clone()
    // Unmark script tags as already being eval'd so they can get executed again
    // when restored from cache. HAXX: Uses jQuery internal method.
    cloned.find('script').each(function(){
      if (!this.src) jQuery._data(this, 'globalEval', false)
    })
    return [selector, cloned.contents()]
  }

  // Internal: Strip internal query params from parsed URL.
  //
  // Returns sanitized url.href String.
  function stripInternalParams(url) {
    url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')
    return url.href.replace(/\?($|#)/, '$1')
  }

  // Internal: Parse URL components and returns a Locationish object.
  //
  // url - String URL
  //
  // Returns HTMLAnchorElement that acts like Location.
  function parseURL(url) {
    var a = document.createElement('a')
    a.href = url
    return a
  }

  // Internal: Return the `href` component of given URL object with the hash
  // portion removed.
  //
  // location - Location or HTMLAnchorElement
  //
  // Returns String
  function stripHash(location) {
    return location.href.replace(/#.*/, '')
  }

  // Internal: Build options Object for arguments.
  //
  // For convenience the first parameter can be either the container or
  // the options object.
  //
  // Examples
  //
  //   optionsFor('#container')
  //   // => {container: '#container'}
  //
  //   optionsFor('#container', {push: true})
  //   // => {container: '#container', push: true}
  //
  //   optionsFor({container: '#container', push: true})
  //   // => {container: '#container', push: true}
  //
  // Returns options Object.
  function optionsFor(container, options) {
    // Both container and options
    if ( container && options )
      options.container = container

    // First argument is options Object
    else if ( $.isPlainObject(container) )
      options = container

    // Only container
    else
      options = {container: container}

    // Find and validate container
    if (options.container)
      options.container = findContainerFor(options.container)

    return options
  }

  // Internal: Find container element for a variety of inputs.
  //
  // Because we can't persist elements using the history API, we must be
  // able to find a String selector that will consistently find the Element.
  //
  // container - A selector String, jQuery object, or DOM Element.
  //
  // Returns a jQuery object whose context is `document` and has a selector.
  function findContainerFor(container) {
    var selector, $container;
    if ( Array.isArray(container) ) {
      $container = container[0]
      selector = container[1]
    } else {
      selector = container
      $container = $(selector)
    }

    if ( !$container.length ) {
      throw "no pjax container for " + selector
    } else if ( true ) {
      return [$container, selector];
    } else if ( container.selector !== '' && container.context === document ) {
      return container
    } else if ( container.attr('id') ) {
      return $('#' + container.attr('id'))
    } else {
      throw "cant get selector for pjax container!"
    }
  }

  // Internal: Filter and find all elements matching the selector.
  //
  // Where $.fn.find only matches descendants, findAll will test all the
  // top level elements in the jQuery object as well.
  //
  // elems    - jQuery object of Elements
  // selector - String selector to match
  //
  // Returns a jQuery object.
  function findAll(elems, selector) {
    return elems.filter(selector).add(elems.find(selector));
  }

  function parseHTML(html) {
    return $.parseHTML(html, document, true)
  }

  // Internal: Extracts container and metadata from response.
  //
  // 1. Extracts X-PJAX-URL header if set
  // 2. Extracts inline <title> tags
  // 3. Builds response Element and extracts fragment if set
  //
  // data    - String response data
  // xhr     - XHR response
  // options - pjax options Object
  //
  // Returns an Object with url, title, and contents keys.
  function extractContainer(data, xhr, options) {
    var obj = {}, fullDocument = /<html/i.test(data)

    // Prefer X-PJAX-URL header if it was set, otherwise fallback to
    // using the original requested url.
    var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
    obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl

    // Attempt to parse response html into elements
    if (fullDocument) {
      var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
      var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
    } else {
      var $head = $body = $(parseHTML(data))
    }

    // If response data is empty, return fast
    if ($body.length === 0)
      return obj

    // If there's a <title> tag in the header, use it as
    // the page's title.
    obj.title = findAll($head, 'title').last().text()

    if (options.fragment) {
      // If they specified a fragment, look for it in the response
      // and pull it out.
      if (options.fragment === 'body') {
        var $fragment = $body
      } else {
        var $fragment = findAll($body, options.fragment).first()
      }

      if ($fragment.length) {
        obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()

        // If there's no title, look for data-title and title attributes
        // on the fragment
        if (!obj.title)
          obj.title = $fragment.attr('title') || $fragment.data('title')
      }

    } else if (!fullDocument) {
      obj.contents = $body
    }

    // Clean up any <title> tags
    if (obj.contents) {
      // Remove any parent title elements
      obj.contents = obj.contents.not(function() { return $(this).is('title') })

      // Then scrub any titles from their descendants
      obj.contents.find('title').remove()

      // Gather all script[src] elements
      obj.scripts = findAll(obj.contents, 'script[src]').remove()
      obj.contents = obj.contents.not(obj.scripts)
    }

    // Trim any whitespace off the title
    if (obj.title) obj.title = $.trim(obj.title)

    return obj
  }

  // Load an execute scripts using standard script request.
  //
  // Avoids jQuery's traditional $.getScript which does a XHR request and
  // globalEval.
  //
  // scripts - jQuery object of script Elements
  //
  // Returns nothing.
  function executeScriptTags(scripts) {
    if (!scripts) return

    var existingScripts = $('script[src]')

    scripts.each(function() {
      var src = this.src
      var matchedScripts = existingScripts.filter(function() {
        return this.src === src
      })
      if (matchedScripts.length) return

      var script = document.createElement('script')
      var type = $(this).attr('type')
      if (type) script.type = type
      script.src = $(this).attr('src')
      document.head.appendChild(script)
    })
  }

  // Internal: History DOM caching class.
  var cacheMapping      = {}
  var cacheForwardStack = []
  var cacheBackStack    = []

  // Push previous state id and container contents into the history
  // cache. Should be called in conjunction with `pushState` to save the
  // previous container contents.
  //
  // id    - State ID Number
  // value - DOM Element to cache
  //
  // Returns nothing.
  function cachePush(id, value) {
    cacheMapping[id] = value
    cacheBackStack.push(id)

    // Remove all entries in forward history stack after pushing a new page.
    trimCacheStack(cacheForwardStack, 0)

    // Trim back history stack to max cache length.
    trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
  }

  // Shifts cache from directional history cache. Should be
  // called on `popstate` with the previous state id and container
  // contents.
  //
  // direction - "forward" or "back" String
  // id        - State ID Number
  // value     - DOM Element to cache
  //
  // Returns nothing.
  function cachePop(direction, id, value) {
    var pushStack, popStack
    cacheMapping[id] = value

    if (direction === 'forward') {
      pushStack = cacheBackStack
      popStack  = cacheForwardStack
    } else {
      pushStack = cacheForwardStack
      popStack  = cacheBackStack
    }

    pushStack.push(id)
    if (id = popStack.pop())
      delete cacheMapping[id]

    // Trim whichever stack we just pushed to to max cache length.
    trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
  }

  // Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
  // longer than the specified length, deleting cached DOM elements as necessary.
  //
  // stack  - Array of state IDs
  // length - Maximum length to trim to
  //
  // Returns nothing.
  function trimCacheStack(stack, length) {
    while (stack.length > length)
      delete cacheMapping[stack.shift()]
  }

  // Public: Find version identifier for the initial page load.
  //
  // Returns String version or undefined.
  function findVersion() {
    return $('meta').filter(function() {
      var name = $(this).attr('http-equiv')
      return name && name.toUpperCase() === 'X-PJAX-VERSION'
    }).attr('content')
  }

  // Install pjax functions on $.pjax to enable pushState behavior.
  //
  // Does nothing if already enabled.
  //
  // Examples
  //
  //     $.pjax.enable()
  //
  // Returns nothing.
  function enable() {
    $.fn.pjax = fnPjax
    $.pjax = pjax
    $.pjax.enable = $.noop
    $.pjax.disable = disable
    $.pjax.click = handleClick
    $.pjax.submit = handleSubmit
    $.pjax.reload = pjaxReload
    $.pjax.defaults = {
      timeout: 650,
      push: true,
      replace: false,
      type: 'GET',
      dataType: 'html',
      scrollTo: 0,
      maxCacheLength: 20,
      version: findVersion
    }
    $(window).on('popstate.pjax', onPjaxPopstate)
  }

  // Disable pushState behavior.
  //
  // This is the case when a browser doesn't support pushState. It is
  // sometimes useful to disable pushState for debugging on a modern
  // browser.
  //
  // Examples
  //
  //     $.pjax.disable()
  //
  // Returns nothing.
  function disable() {
    $.fn.pjax = function() { return this }
    $.pjax = fallbackPjax
    $.pjax.enable = enable
    $.pjax.disable = $.noop
    $.pjax.click = $.noop
    $.pjax.submit = $.noop
    $.pjax.reload = function() { window.location.reload() }

    $(window).off('popstate.pjax', onPjaxPopstate)
  }


  // Add the state property to jQuery's event object so we can use it in
  // $(window).bind('popstate')
  if ( $.event.props && $.inArray('state', $.event.props) < 0 ) {
    $.event.props.push('state');
  } else if ( ! ('state' in $.Event.prototype) ) {
    $.event.addProp('state');
  }

  // Is pjax supported by this browser?
  $.support.pjax =
      window.history && window.history.pushState && window.history.replaceState &&
      // pushState isn't reliable on iOS until 5.
      !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)

  $.support.pjax ? enable() : disable()

})(jQuery);