// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_DEQUE
#define _LIBCPP_DEQUE

/*
    deque synopsis

namespace std
{

template <class T, class Allocator = allocator<T> >
class deque
{
public:
    // types:
    typedef T value_type;
    typedef Allocator allocator_type;

    typedef typename allocator_type::reference       reference;
    typedef typename allocator_type::const_reference const_reference;
    typedef implementation-defined                   iterator;
    typedef implementation-defined                   const_iterator;
    typedef typename allocator_type::size_type       size_type;
    typedef typename allocator_type::difference_type difference_type;

    typedef typename allocator_type::pointer         pointer;
    typedef typename allocator_type::const_pointer   const_pointer;
    typedef std::reverse_iterator<iterator>          reverse_iterator;
    typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;

    // construct/copy/destroy:
    deque() noexcept(is_nothrow_default_constructible<allocator_type>::value);
    explicit deque(const allocator_type& a);
    explicit deque(size_type n);
    explicit deque(size_type n, const allocator_type& a); // C++14
    deque(size_type n, const value_type& v);
    deque(size_type n, const value_type& v, const allocator_type& a);
    template <class InputIterator>
        deque(InputIterator f, InputIterator l);
    template <class InputIterator>
        deque(InputIterator f, InputIterator l, const allocator_type& a);
    deque(const deque& c);
    deque(deque&& c)
        noexcept(is_nothrow_move_constructible<allocator_type>::value);
    deque(initializer_list<value_type> il, const Allocator& a = allocator_type());
    deque(const deque& c, const allocator_type& a);
    deque(deque&& c, const allocator_type& a);
    ~deque();

    deque& operator=(const deque& c);
    deque& operator=(deque&& c)
        noexcept(
             allocator_type::propagate_on_container_move_assignment::value &&
             is_nothrow_move_assignable<allocator_type>::value);
    deque& operator=(initializer_list<value_type> il);

    template <class InputIterator>
        void assign(InputIterator f, InputIterator l);
    void assign(size_type n, const value_type& v);
    void assign(initializer_list<value_type> il);

    allocator_type get_allocator() const noexcept;

    // iterators:

    iterator       begin() noexcept;
    const_iterator begin() const noexcept;
    iterator       end() noexcept;
    const_iterator end() const noexcept;

    reverse_iterator       rbegin() noexcept;
    const_reverse_iterator rbegin() const noexcept;
    reverse_iterator       rend() noexcept;
    const_reverse_iterator rend() const noexcept;

    const_iterator         cbegin() const noexcept;
    const_iterator         cend() const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    const_reverse_iterator crend() const noexcept;

    // capacity:
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    void resize(size_type n);
    void resize(size_type n, const value_type& v);
    void shrink_to_fit();
    bool empty() const noexcept;

    // element access:
    reference operator[](size_type i);
    const_reference operator[](size_type i) const;
    reference at(size_type i);
    const_reference at(size_type i) const;
    reference front();
    const_reference front() const;
    reference back();
    const_reference back() const;

    // modifiers:
    void push_front(const value_type& v);
    void push_front(value_type&& v);
    void push_back(const value_type& v);
    void push_back(value_type&& v);
    template <class... Args> reference emplace_front(Args&&... args);  // reference in C++17
    template <class... Args> reference emplace_back(Args&&... args);   // reference in C++17
    template <class... Args> iterator emplace(const_iterator p, Args&&... args);
    iterator insert(const_iterator p, const value_type& v);
    iterator insert(const_iterator p, value_type&& v);
    iterator insert(const_iterator p, size_type n, const value_type& v);
    template <class InputIterator>
        iterator insert(const_iterator p, InputIterator f, InputIterator l);
    iterator insert(const_iterator p, initializer_list<value_type> il);
    void pop_front();
    void pop_back();
    iterator erase(const_iterator p);
    iterator erase(const_iterator f, const_iterator l);
    void swap(deque& c)
        noexcept(allocator_traits<allocator_type>::is_always_equal::value);  // C++17
    void clear() noexcept;
};

template <class InputIterator, class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
   deque(InputIterator, InputIterator, Allocator = Allocator())
   -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17

template <class T, class Allocator>
    bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
template <class T, class Allocator>
    bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
template <class T, class Allocator>
    bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
template <class T, class Allocator>
    bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
template <class T, class Allocator>
    bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
template <class T, class Allocator>
    bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);

// specialized algorithms:
template <class T, class Allocator>
    void swap(deque<T,Allocator>& x, deque<T,Allocator>& y)
         noexcept(noexcept(x.swap(y)));

template <class T, class Allocator, class U>
    typename deque<T, Allocator>::size_type
    erase(deque<T, Allocator>& c, const U& value);       // C++20
template <class T, class Allocator, class Predicate>
    typename deque<T, Allocator>::size_type
    erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20

}  // std

*/

#include <__algorithm/copy.h>
#include <__algorithm/copy_backward.h>
#include <__algorithm/equal.h>
#include <__algorithm/fill_n.h>
#include <__algorithm/lexicographical_compare.h>
#include <__algorithm/min.h>
#include <__algorithm/remove.h>
#include <__algorithm/remove_if.h>
#include <__algorithm/unwrap_iter.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__format/enable_insertable.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/next.h>
#include <__iterator/prev.h>
#include <__iterator/reverse_iterator.h>
#include <__iterator/segmented_iterator.h>
#include <__memory/allocator_destructor.h>
#include <__memory/pointer_traits.h>
#include <__memory/temp_value.h>
#include <__memory/unique_ptr.h>
#include <__memory_resource/polymorphic_allocator.h>
#include <__split_buffer>
#include <__type_traits/is_allocator.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <version>

// standard-mandated includes

// [iterator.range]
#include <__iterator/access.h>
#include <__iterator/data.h>
#include <__iterator/empty.h>
#include <__iterator/reverse_access.h>
#include <__iterator/size.h>

// [deque.syn]
#include <compare>
#include <initializer_list>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>


_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp, class _Allocator = allocator<_Tp> > class _LIBCPP_TEMPLATE_VIS deque;

template <class _ValueType, class _DiffType>
struct __deque_block_size {
  static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
};

template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
          class _DiffType, _DiffType _BS =
#ifdef _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
// Keep template parameter to avoid changing all template declarations thoughout
// this file.
                               0
#else
                               __deque_block_size<_ValueType, _DiffType>::value
#endif
          >
class _LIBCPP_TEMPLATE_VIS __deque_iterator
{
    typedef _MapPointer __map_iterator;
public:
    typedef _Pointer  pointer;
    typedef _DiffType difference_type;
private:
    __map_iterator __m_iter_;
    pointer        __ptr_;

    static const difference_type __block_size;
public:
    typedef _ValueType                  value_type;
    typedef random_access_iterator_tag  iterator_category;
    typedef _Reference                  reference;

    _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT
#if _LIBCPP_STD_VER > 11
     : __m_iter_(nullptr), __ptr_(nullptr)
#endif
     {}

    template <class _Pp, class _Rp, class _MP>
    _LIBCPP_HIDE_FROM_ABI
    __deque_iterator(const __deque_iterator<value_type, _Pp, _Rp, _MP, difference_type, _BS>& __it,
                typename enable_if<is_convertible<_Pp, pointer>::value>::type* = 0) _NOEXCEPT
        : __m_iter_(__it.__m_iter_), __ptr_(__it.__ptr_) {}

    _LIBCPP_HIDE_FROM_ABI reference operator*() const {return *__ptr_;}
    _LIBCPP_HIDE_FROM_ABI pointer operator->() const {return __ptr_;}

    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator++()
    {
        if (++__ptr_ - *__m_iter_ == __block_size)
        {
            ++__m_iter_;
            __ptr_ = *__m_iter_;
        }
        return *this;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator++(int)
    {
        __deque_iterator __tmp = *this;
        ++(*this);
        return __tmp;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator--()
    {
        if (__ptr_ == *__m_iter_)
        {
            --__m_iter_;
            __ptr_ = *__m_iter_ + __block_size;
        }
        --__ptr_;
        return *this;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator--(int)
    {
        __deque_iterator __tmp = *this;
        --(*this);
        return __tmp;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator+=(difference_type __n)
    {
        if (__n != 0)
        {
            __n += __ptr_ - *__m_iter_;
            if (__n > 0)
            {
                __m_iter_ += __n / __block_size;
                __ptr_ = *__m_iter_ + __n % __block_size;
            }
            else // (__n < 0)
            {
                difference_type __z = __block_size - 1 - __n;
                __m_iter_ -= __z / __block_size;
                __ptr_ = *__m_iter_ + (__block_size - 1 - __z % __block_size);
            }
        }
        return *this;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator& operator-=(difference_type __n)
    {
        return *this += -__n;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator+(difference_type __n) const
    {
        __deque_iterator __t(*this);
        __t += __n;
        return __t;
    }

    _LIBCPP_HIDE_FROM_ABI __deque_iterator operator-(difference_type __n) const
    {
        __deque_iterator __t(*this);
        __t -= __n;
        return __t;
    }

    _LIBCPP_HIDE_FROM_ABI
    friend __deque_iterator operator+(difference_type __n, const __deque_iterator& __it)
        {return __it + __n;}

    _LIBCPP_HIDE_FROM_ABI
    friend difference_type operator-(const __deque_iterator& __x, const __deque_iterator& __y)
    {
        if (__x != __y)
            return (__x.__m_iter_ - __y.__m_iter_) * __block_size
                 + (__x.__ptr_ - *__x.__m_iter_)
                 - (__y.__ptr_ - *__y.__m_iter_);
        return 0;
    }

    _LIBCPP_HIDE_FROM_ABI reference operator[](difference_type __n) const
        {return *(*this + __n);}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator==(const __deque_iterator& __x, const __deque_iterator& __y)
        {return __x.__ptr_ == __y.__ptr_;}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y)
        {return !(__x == __y);}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator<(const __deque_iterator& __x, const __deque_iterator& __y)
        {return __x.__m_iter_ < __y.__m_iter_ ||
               (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator>(const __deque_iterator& __x, const __deque_iterator& __y)
        {return __y < __x;}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator<=(const __deque_iterator& __x, const __deque_iterator& __y)
        {return !(__y < __x);}

    _LIBCPP_HIDE_FROM_ABI friend
        bool operator>=(const __deque_iterator& __x, const __deque_iterator& __y)
        {return !(__x < __y);}

private:
    _LIBCPP_HIDE_FROM_ABI explicit __deque_iterator(__map_iterator __m, pointer __p) _NOEXCEPT
        : __m_iter_(__m), __ptr_(__p) {}

    template <class _Tp, class _Ap> friend class _LIBCPP_TEMPLATE_VIS deque;
    template <class _Vp, class _Pp, class _Rp, class _MP, class _Dp, _Dp>
        friend class _LIBCPP_TEMPLATE_VIS __deque_iterator;

    template <class>
    friend struct __segmented_iterator_traits;
};

template <class _ValueType, class _Pointer, class _Reference, class _MapPointer, class _DiffType, _DiffType _BlockSize>
struct __segmented_iterator_traits<
    __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize> > {
private:
  using _Iterator = __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer, _DiffType, _BlockSize>;

public:
  using __is_segmented_iterator = true_type;
  using __segment_iterator = _MapPointer;
  using __local_iterator = _Pointer;

  static _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_Iterator __iter) { return __iter.__m_iter_; }
  static _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_Iterator __iter) { return __iter.__ptr_; }
  static _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) { return *__iter; }

  static _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
        return *__iter + _Iterator::__block_size;
  }

  static _LIBCPP_HIDE_FROM_ABI _Iterator __compose(__segment_iterator __segment, __local_iterator __local) {
        if (__local == __end(__segment)) {
            ++__segment;
            return _Iterator(__segment, *__segment);
        }
        return _Iterator(__segment, __local);
  }
};

template <class _ValueType, class _Pointer, class _Reference, class _MapPointer,
          class _DiffType, _DiffType _BlockSize>
const _DiffType __deque_iterator<_ValueType, _Pointer, _Reference, _MapPointer,
                                 _DiffType, _BlockSize>::__block_size =
    __deque_block_size<_ValueType, _DiffType>::value;

template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
class _LIBCPP_TEMPLATE_VIS deque
{
public:
    // types:

  using value_type = _Tp;

  static_assert((is_same<typename _Allocator::value_type, value_type>::value),
                "Allocator::value_type must be same type as value_type");

  using allocator_type = _Allocator;
  using __alloc_traits = allocator_traits<allocator_type>;

  using size_type       = typename __alloc_traits::size_type;
  using difference_type = typename __alloc_traits::difference_type;

  using pointer       = typename __alloc_traits::pointer;
  using const_pointer = typename __alloc_traits::const_pointer;

  using __pointer_allocator       = __rebind_alloc<__alloc_traits, pointer>;
  using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>;
  using __map                     = __split_buffer<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           