Index: trip-planner-front/node_modules/bootstrap/js/src/alert.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/alert.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/alert.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,99 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { defineJQueryPlugin } from './util/index'
+import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
+import { enableDismissTrigger } from './util/component-functions'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'alert'
+const DATA_KEY = 'bs.alert'
+const EVENT_KEY = `.${DATA_KEY}`
+
+const EVENT_CLOSE = `close${EVENT_KEY}`
+const EVENT_CLOSED = `closed${EVENT_KEY}`
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Alert extends BaseComponent {
+  // Getters
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  close() {
+    const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)
+
+    if (closeEvent.defaultPrevented) {
+      return
+    }
+
+    this._element.classList.remove(CLASS_NAME_SHOW)
+
+    const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)
+    this._queueCallback(() => this._destroyElement(), this._element, isAnimated)
+  }
+
+  // Private
+  _destroyElement() {
+    this._element.remove()
+    EventHandler.trigger(this._element, EVENT_CLOSED)
+    this.dispose()
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Alert.getOrCreateInstance(this)
+
+      if (typeof config !== 'string') {
+        return
+      }
+
+      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
+        throw new TypeError(`No method named "${config}"`)
+      }
+
+      data[config](this)
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+enableDismissTrigger(Alert, 'close')
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Alert to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Alert)
+
+export default Alert
Index: trip-planner-front/node_modules/bootstrap/js/src/base-component.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/base-component.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/base-component.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,75 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): base-component.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import Data from './dom/data'
+import {
+  executeAfterTransition,
+  getElement
+} from './util/index'
+import EventHandler from './dom/event-handler'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const VERSION = '5.1.3'
+
+class BaseComponent {
+  constructor(element) {
+    element = getElement(element)
+
+    if (!element) {
+      return
+    }
+
+    this._element = element
+    Data.set(this._element, this.constructor.DATA_KEY, this)
+  }
+
+  dispose() {
+    Data.remove(this._element, this.constructor.DATA_KEY)
+    EventHandler.off(this._element, this.constructor.EVENT_KEY)
+
+    Object.getOwnPropertyNames(this).forEach(propertyName => {
+      this[propertyName] = null
+    })
+  }
+
+  _queueCallback(callback, element, isAnimated = true) {
+    executeAfterTransition(callback, element, isAnimated)
+  }
+
+  /** Static */
+
+  static getInstance(element) {
+    return Data.get(getElement(element), this.DATA_KEY)
+  }
+
+  static getOrCreateInstance(element, config = {}) {
+    return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
+  }
+
+  static get VERSION() {
+    return VERSION
+  }
+
+  static get NAME() {
+    throw new Error('You have to implement the static method "NAME", for each component!')
+  }
+
+  static get DATA_KEY() {
+    return `bs.${this.NAME}`
+  }
+
+  static get EVENT_KEY() {
+    return `.${this.DATA_KEY}`
+  }
+}
+
+export default BaseComponent
Index: trip-planner-front/node_modules/bootstrap/js/src/button.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/button.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/button.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,86 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { defineJQueryPlugin } from './util/index'
+import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'button'
+const DATA_KEY = 'bs.button'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const CLASS_NAME_ACTIVE = 'active'
+
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]'
+
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Button extends BaseComponent {
+  // Getters
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  toggle() {
+    // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
+    this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Button.getOrCreateInstance(this)
+
+      if (config === 'toggle') {
+        data[config]()
+      }
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
+  event.preventDefault()
+
+  const button = event.target.closest(SELECTOR_DATA_TOGGLE)
+  const data = Button.getOrCreateInstance(button)
+
+  data.toggle()
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Button to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Button)
+
+export default Button
Index: trip-planner-front/node_modules/bootstrap/js/src/carousel.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/carousel.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/carousel.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,591 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): carousel.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElementFromSelector,
+  isRTL,
+  isVisible,
+  getNextActiveElement,
+  reflow,
+  triggerTransitionEnd,
+  typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'carousel'
+const DATA_KEY = 'bs.carousel'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const ARROW_LEFT_KEY = 'ArrowLeft'
+const ARROW_RIGHT_KEY = 'ArrowRight'
+const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
+const SWIPE_THRESHOLD = 40
+
+const Default = {
+  interval: 5000,
+  keyboard: true,
+  slide: false,
+  pause: 'hover',
+  wrap: true,
+  touch: true
+}
+
+const DefaultType = {
+  interval: '(number|boolean)',
+  keyboard: 'boolean',
+  slide: '(boolean|string)',
+  pause: '(string|boolean)',
+  wrap: 'boolean',
+  touch: 'boolean'
+}
+
+const ORDER_NEXT = 'next'
+const ORDER_PREV = 'prev'
+const DIRECTION_LEFT = 'left'
+const DIRECTION_RIGHT = 'right'
+
+const KEY_TO_DIRECTION = {
+  [ARROW_LEFT_KEY]: DIRECTION_RIGHT,
+  [ARROW_RIGHT_KEY]: DIRECTION_LEFT
+}
+
+const EVENT_SLIDE = `slide${EVENT_KEY}`
+const EVENT_SLID = `slid${EVENT_KEY}`
+const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
+const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`
+const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`
+const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`
+const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`
+const EVENT_TOUCHEND = `touchend${EVENT_KEY}`
+const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`
+const EVENT_POINTERUP = `pointerup${EVENT_KEY}`
+const EVENT_DRAG_START = `dragstart${EVENT_KEY}`
+const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_CAROUSEL = 'carousel'
+const CLASS_NAME_ACTIVE = 'active'
+const CLASS_NAME_SLIDE = 'slide'
+const CLASS_NAME_END = 'carousel-item-end'
+const CLASS_NAME_START = 'carousel-item-start'
+const CLASS_NAME_NEXT = 'carousel-item-next'
+const CLASS_NAME_PREV = 'carousel-item-prev'
+const CLASS_NAME_POINTER_EVENT = 'pointer-event'
+
+const SELECTOR_ACTIVE = '.active'
+const SELECTOR_ACTIVE_ITEM = '.active.carousel-item'
+const SELECTOR_ITEM = '.carousel-item'
+const SELECTOR_ITEM_IMG = '.carousel-item img'
+const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
+const SELECTOR_INDICATORS = '.carousel-indicators'
+const SELECTOR_INDICATOR = '[data-bs-target]'
+const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'
+const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'
+
+const POINTER_TYPE_TOUCH = 'touch'
+const POINTER_TYPE_PEN = 'pen'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+class Carousel extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._items = null
+    this._interval = null
+    this._activeElement = null
+    this._isPaused = false
+    this._isSliding = false
+    this.touchTimeout = null
+    this.touchStartX = 0
+    this.touchDeltaX = 0
+
+    this._config = this._getConfig(config)
+    this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
+    this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
+    this._pointerEvent = Boolean(window.PointerEvent)
+
+    this._addEventListeners()
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  next() {
+    this._slide(ORDER_NEXT)
+  }
+
+  nextWhenVisible() {
+    // Don't call next when the page isn't visible
+    // or the carousel or its parent isn't visible
+    if (!document.hidden && isVisible(this._element)) {
+      this.next()
+    }
+  }
+
+  prev() {
+    this._slide(ORDER_PREV)
+  }
+
+  pause(event) {
+    if (!event) {
+      this._isPaused = true
+    }
+
+    if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {
+      triggerTransitionEnd(this._element)
+      this.cycle(true)
+    }
+
+    clearInterval(this._interval)
+    this._interval = null
+  }
+
+  cycle(event) {
+    if (!event) {
+      this._isPaused = false
+    }
+
+    if (this._interval) {
+      clearInterval(this._interval)
+      this._interval = null
+    }
+
+    if (this._config && this._config.interval && !this._isPaused) {
+      this._updateInterval()
+
+      this._interval = setInterval(
+        (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
+        this._config.interval
+      )
+    }
+  }
+
+  to(index) {
+    this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
+    const activeIndex = this._getItemIndex(this._activeElement)
+
+    if (index > this._items.length - 1 || index < 0) {
+      return
+    }
+
+    if (this._isSliding) {
+      EventHandler.one(this._element, EVENT_SLID, () => this.to(index))
+      return
+    }
+
+    if (activeIndex === index) {
+      this.pause()
+      this.cycle()
+      return
+    }
+
+    const order = index > activeIndex ?
+      ORDER_NEXT :
+      ORDER_PREV
+
+    this._slide(order, this._items[index])
+  }
+
+  // Private
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...(typeof config === 'object' ? config : {})
+    }
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+
+  _handleSwipe() {
+    const absDeltax = Math.abs(this.touchDeltaX)
+
+    if (absDeltax <= SWIPE_THRESHOLD) {
+      return
+    }
+
+    const direction = absDeltax / this.touchDeltaX
+
+    this.touchDeltaX = 0
+
+    if (!direction) {
+      return
+    }
+
+    this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT)
+  }
+
+  _addEventListeners() {
+    if (this._config.keyboard) {
+      EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
+    }
+
+    if (this._config.pause === 'hover') {
+      EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event))
+      EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event))
+    }
+
+    if (this._config.touch && this._touchSupported) {
+      this._addTouchEventListeners()
+    }
+  }
+
+  _addTouchEventListeners() {
+    const hasPointerPenTouch = event => {
+      return this._pointerEvent &&
+        (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
+    }
+
+    const start = event => {
+      if (hasPointerPenTouch(event)) {
+        this.touchStartX = event.clientX
+      } else if (!this._pointerEvent) {
+        this.touchStartX = event.touches[0].clientX
+      }
+    }
+
+    const move = event => {
+      // ensure swiping with one touch and not pinching
+      this.touchDeltaX = event.touches && event.touches.length > 1 ?
+        0 :
+        event.touches[0].clientX - this.touchStartX
+    }
+
+    const end = event => {
+      if (hasPointerPenTouch(event)) {
+        this.touchDeltaX = event.clientX - this.touchStartX
+      }
+
+      this._handleSwipe()
+      if (this._config.pause === 'hover') {
+        // If it's a touch-enabled device, mouseenter/leave are fired as
+        // part of the mouse compatibility events on first tap - the carousel
+        // would stop cycling until user tapped out of it;
+        // here, we listen for touchend, explicitly pause the carousel
+        // (as if it's the second time we tap on it, mouseenter compat event
+        // is NOT fired) and after a timeout (to allow for mouse compatibility
+        // events to fire) we explicitly restart cycling
+
+        this.pause()
+        if (this.touchTimeout) {
+          clearTimeout(this.touchTimeout)
+        }
+
+        this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
+      }
+    }
+
+    SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {
+      EventHandler.on(itemImg, EVENT_DRAG_START, event => event.preventDefault())
+    })
+
+    if (this._pointerEvent) {
+      EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event))
+      EventHandler.on(this._element, EVENT_POINTERUP, event => end(event))
+
+      this._element.classList.add(CLASS_NAME_POINTER_EVENT)
+    } else {
+      EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event))
+      EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event))
+      EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event))
+    }
+  }
+
+  _keydown(event) {
+    if (/input|textarea/i.test(event.target.tagName)) {
+      return
+    }
+
+    const direction = KEY_TO_DIRECTION[event.key]
+    if (direction) {
+      event.preventDefault()
+      this._slide(direction)
+    }
+  }
+
+  _getItemIndex(element) {
+    this._items = element && element.parentNode ?
+      SelectorEngine.find(SELECTOR_ITEM, element.parentNode) :
+      []
+
+    return this._items.indexOf(element)
+  }
+
+  _getItemByOrder(order, activeElement) {
+    const isNext = order === ORDER_NEXT
+    return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap)
+  }
+
+  _triggerSlideEvent(relatedTarget, eventDirectionName) {
+    const targetIndex = this._getItemIndex(relatedTarget)
+    const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element))
+
+    return EventHandler.trigger(this._element, EVENT_SLIDE, {
+      relatedTarget,
+      direction: eventDirectionName,
+      from: fromIndex,
+      to: targetIndex
+    })
+  }
+
+  _setActiveIndicatorElement(element) {
+    if (this._indicatorsElement) {
+      const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)
+
+      activeIndicator.classList.remove(CLASS_NAME_ACTIVE)
+      activeIndicator.removeAttribute('aria-current')
+
+      const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement)
+
+      for (let i = 0; i < indicators.length; i++) {
+        if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {
+          indicators[i].classList.add(CLASS_NAME_ACTIVE)
+          indicators[i].setAttribute('aria-current', 'true')
+          break
+        }
+      }
+    }
+  }
+
+  _updateInterval() {
+    const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
+
+    if (!element) {
+      return
+    }
+
+    const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)
+
+    if (elementInterval) {
+      this._config.defaultInterval = this._config.defaultInterval || this._config.interval
+      this._config.interval = elementInterval
+    } else {
+      this._config.interval = this._config.defaultInterval || this._config.interval
+    }
+  }
+
+  _slide(directionOrOrder, element) {
+    const order = this._directionToOrder(directionOrOrder)
+    const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
+    const activeElementIndex = this._getItemIndex(activeElement)
+    const nextElement = element || this._getItemByOrder(order, activeElement)
+
+    const nextElementIndex = this._getItemIndex(nextElement)
+    const isCycling = Boolean(this._interval)
+
+    const isNext = order === ORDER_NEXT
+    const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END
+    const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV
+    const eventDirectionName = this._orderToDirection(order)
+
+    if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
+      this._isSliding = false
+      return
+    }
+
+    if (this._isSliding) {
+      return
+    }
+
+    const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
+    if (slideEvent.defaultPrevented) {
+      return
+    }
+
+    if (!activeElement || !nextElement) {
+      // Some weirdness is happening, so we bail
+      return
+    }
+
+    this._isSliding = true
+
+    if (isCycling) {
+      this.pause()
+    }
+
+    this._setActiveIndicatorElement(nextElement)
+    this._activeElement = nextElement
+
+    const triggerSlidEvent = () => {
+      EventHandler.trigger(this._element, EVENT_SLID, {
+        relatedTarget: nextElement,
+        direction: eventDirectionName,
+        from: activeElementIndex,
+        to: nextElementIndex
+      })
+    }
+
+    if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
+      nextElement.classList.add(orderClassName)
+
+      reflow(nextElement)
+
+      activeElement.classList.add(directionalClassName)
+      nextElement.classList.add(directionalClassName)
+
+      const completeCallBack = () => {
+        nextElement.classList.remove(directionalClassName, orderClassName)
+        nextElement.classList.add(CLASS_NAME_ACTIVE)
+
+        activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)
+
+        this._isSliding = false
+
+        setTimeout(triggerSlidEvent, 0)
+      }
+
+      this._queueCallback(completeCallBack, activeElement, true)
+    } else {
+      activeElement.classList.remove(CLASS_NAME_ACTIVE)
+      nextElement.classList.add(CLASS_NAME_ACTIVE)
+
+      this._isSliding = false
+      triggerSlidEvent()
+    }
+
+    if (isCycling) {
+      this.cycle()
+    }
+  }
+
+  _directionToOrder(direction) {
+    if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {
+      return direction
+    }
+
+    if (isRTL()) {
+      return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT
+    }
+
+    return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV
+  }
+
+  _orderToDirection(order) {
+    if (![ORDER_NEXT, ORDER_PREV].includes(order)) {
+      return order
+    }
+
+    if (isRTL()) {
+      return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT
+    }
+
+    return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT
+  }
+
+  // Static
+
+  static carouselInterface(element, config) {
+    const data = Carousel.getOrCreateInstance(element, config)
+
+    let { _config } = data
+    if (typeof config === 'object') {
+      _config = {
+        ..._config,
+        ...config
+      }
+    }
+
+    const action = typeof config === 'string' ? config : _config.slide
+
+    if (typeof config === 'number') {
+      data.to(config)
+    } else if (typeof action === 'string') {
+      if (typeof data[action] === 'undefined') {
+        throw new TypeError(`No method named "${action}"`)
+      }
+
+      data[action]()
+    } else if (_config.interval && _config.ride) {
+      data.pause()
+      data.cycle()
+    }
+  }
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      Carousel.carouselInterface(this, config)
+    })
+  }
+
+  static dataApiClickHandler(event) {
+    const target = getElementFromSelector(this)
+
+    if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
+      return
+    }
+
+    const config = {
+      ...Manipulator.getDataAttributes(target),
+      ...Manipulator.getDataAttributes(this)
+    }
+    const slideIndex = this.getAttribute('data-bs-slide-to')
+
+    if (slideIndex) {
+      config.interval = false
+    }
+
+    Carousel.carouselInterface(target, config)
+
+    if (slideIndex) {
+      Carousel.getInstance(target).to(slideIndex)
+    }
+
+    event.preventDefault()
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler)
+
+EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
+  const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)
+
+  for (let i = 0, len = carousels.length; i < len; i++) {
+    Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]))
+  }
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Carousel to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Carousel)
+
+export default Carousel
Index: trip-planner-front/node_modules/bootstrap/js/src/collapse.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/collapse.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/collapse.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,335 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElement,
+  getSelectorFromElement,
+  getElementFromSelector,
+  reflow,
+  typeCheckConfig
+} from './util/index'
+import Data from './dom/data'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'collapse'
+const DATA_KEY = 'bs.collapse'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const Default = {
+  toggle: true,
+  parent: null
+}
+
+const DefaultType = {
+  toggle: 'boolean',
+  parent: '(null|element)'
+}
+
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_COLLAPSE = 'collapse'
+const CLASS_NAME_COLLAPSING = 'collapsing'
+const CLASS_NAME_COLLAPSED = 'collapsed'
+const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`
+const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'
+
+const WIDTH = 'width'
+const HEIGHT = 'height'
+
+const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Collapse extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._isTransitioning = false
+    this._config = this._getConfig(config)
+    this._triggerArray = []
+
+    const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
+
+    for (let i = 0, len = toggleList.length; i < len; i++) {
+      const elem = toggleList[i]
+      const selector = getSelectorFromElement(elem)
+      const filterElement = SelectorEngine.find(selector)
+        .filter(foundElem => foundElem === this._element)
+
+      if (selector !== null && filterElement.length) {
+        this._selector = selector
+        this._triggerArray.push(elem)
+      }
+    }
+
+    this._initializeChildren()
+
+    if (!this._config.parent) {
+      this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())
+    }
+
+    if (this._config.toggle) {
+      this.toggle()
+    }
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  toggle() {
+    if (this._isShown()) {
+      this.hide()
+    } else {
+      this.show()
+    }
+  }
+
+  show() {
+    if (this._isTransitioning || this._isShown()) {
+      return
+    }
+
+    let actives = []
+    let activesData
+
+    if (this._config.parent) {
+      const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)
+      actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)) // remove children if greater depth
+    }
+
+    const container = SelectorEngine.findOne(this._selector)
+    if (actives.length) {
+      const tempActiveData = actives.find(elem => container !== elem)
+      activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null
+
+      if (activesData && activesData._isTransitioning) {
+        return
+      }
+    }
+
+    const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)
+    if (startEvent.defaultPrevented) {
+      return
+    }
+
+    actives.forEach(elemActive => {
+      if (container !== elemActive) {
+        Collapse.getOrCreateInstance(elemActive, { toggle: false }).hide()
+      }
+
+      if (!activesData) {
+        Data.set(elemActive, DATA_KEY, null)
+      }
+    })
+
+    const dimension = this._getDimension()
+
+    this._element.classList.remove(CLASS_NAME_COLLAPSE)
+    this._element.classList.add(CLASS_NAME_COLLAPSING)
+
+    this._element.style[dimension] = 0
+
+    this._addAriaAndCollapsedClass(this._triggerArray, true)
+    this._isTransitioning = true
+
+    const complete = () => {
+      this._isTransitioning = false
+
+      this._element.classList.remove(CLASS_NAME_COLLAPSING)
+      this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
+
+      this._element.style[dimension] = ''
+
+      EventHandler.trigger(this._element, EVENT_SHOWN)
+    }
+
+    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
+    const scrollSize = `scroll${capitalizedDimension}`
+
+    this._queueCallback(complete, this._element, true)
+    this._element.style[dimension] = `${this._element[scrollSize]}px`
+  }
+
+  hide() {
+    if (this._isTransitioning || !this._isShown()) {
+      return
+    }
+
+    const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)
+    if (startEvent.defaultPrevented) {
+      return
+    }
+
+    const dimension = this._getDimension()
+
+    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
+
+    reflow(this._element)
+
+    this._element.classList.add(CLASS_NAME_COLLAPSING)
+    this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
+
+    const triggerArrayLength = this._triggerArray.length
+    for (let i = 0; i < triggerArrayLength; i++) {
+      const trigger = this._triggerArray[i]
+      const elem = getElementFromSelector(trigger)
+
+      if (elem && !this._isShown(elem)) {
+        this._addAriaAndCollapsedClass([trigger], false)
+      }
+    }
+
+    this._isTransitioning = true
+
+    const complete = () => {
+      this._isTransitioning = false
+      this._element.classList.remove(CLASS_NAME_COLLAPSING)
+      this._element.classList.add(CLASS_NAME_COLLAPSE)
+      EventHandler.trigger(this._element, EVENT_HIDDEN)
+    }
+
+    this._element.style[dimension] = ''
+
+    this._queueCallback(complete, this._element, true)
+  }
+
+  _isShown(element = this._element) {
+    return element.classList.contains(CLASS_NAME_SHOW)
+  }
+
+  // Private
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...config
+    }
+    config.toggle = Boolean(config.toggle) // Coerce string values
+    config.parent = getElement(config.parent)
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+
+  _getDimension() {
+    return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT
+  }
+
+  _initializeChildren() {
+    if (!this._config.parent) {
+      return
+    }
+
+    const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)
+    SelectorEngine.find(SELECTOR_DATA_TOGGLE, this._config.parent).filter(elem => !children.includes(elem))
+      .forEach(element => {
+        const selected = getElementFromSelector(element)
+
+        if (selected) {
+          this._addAriaAndCollapsedClass([element], this._isShown(selected))
+        }
+      })
+  }
+
+  _addAriaAndCollapsedClass(triggerArray, isOpen) {
+    if (!triggerArray.length) {
+      return
+    }
+
+    triggerArray.forEach(elem => {
+      if (isOpen) {
+        elem.classList.remove(CLASS_NAME_COLLAPSED)
+      } else {
+        elem.classList.add(CLASS_NAME_COLLAPSED)
+      }
+
+      elem.setAttribute('aria-expanded', isOpen)
+    })
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const _config = {}
+      if (typeof config === 'string' && /show|hide/.test(config)) {
+        _config.toggle = false
+      }
+
+      const data = Collapse.getOrCreateInstance(this, _config)
+
+      if (typeof config === 'string') {
+        if (typeof data[config] === 'undefined') {
+          throw new TypeError(`No method named "${config}"`)
+        }
+
+        data[config]()
+      }
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
+  if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {
+    event.preventDefault()
+  }
+
+  const selector = getSelectorFromElement(this)
+  const selectorElements = SelectorEngine.find(selector)
+
+  selectorElements.forEach(element => {
+    Collapse.getOrCreateInstance(element, { toggle: false }).toggle()
+  })
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Collapse to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Collapse)
+
+export default Collapse
Index: trip-planner-front/node_modules/bootstrap/js/src/dom/data.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/dom/data.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/dom/data.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,57 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): dom/data.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const elementMap = new Map()
+
+export default {
+  set(element, key, instance) {
+    if (!elementMap.has(element)) {
+      elementMap.set(element, new Map())
+    }
+
+    const instanceMap = elementMap.get(element)
+
+    // make it clear we only want one instance per element
+    // can be removed later when multiple key/instances are fine to be used
+    if (!instanceMap.has(key) && instanceMap.size !== 0) {
+      // eslint-disable-next-line no-console
+      console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)
+      return
+    }
+
+    instanceMap.set(key, instance)
+  },
+
+  get(element, key) {
+    if (elementMap.has(element)) {
+      return elementMap.get(element).get(key) || null
+    }
+
+    return null
+  },
+
+  remove(element, key) {
+    if (!elementMap.has(element)) {
+      return
+    }
+
+    const instanceMap = elementMap.get(element)
+
+    instanceMap.delete(key)
+
+    // free up element references if there are no instances left for an element
+    if (instanceMap.size === 0) {
+      elementMap.delete(element)
+    }
+  }
+}
Index: trip-planner-front/node_modules/bootstrap/js/src/dom/event-handler.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/dom/event-handler.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/dom/event-handler.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,348 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): dom/event-handler.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { getjQuery } from '../util/index'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const namespaceRegex = /[^.]*(?=\..*)\.|.*/
+const stripNameRegex = /\..*/
+const stripUidRegex = /::\d+$/
+const eventRegistry = {} // Events storage
+let uidEvent = 1
+const customEvents = {
+  mouseenter: 'mouseover',
+  mouseleave: 'mouseout'
+}
+const customEventsRegex = /^(mouseenter|mouseleave)/i
+const nativeEvents = new Set([
+  'click',
+  'dblclick',
+  'mouseup',
+  'mousedown',
+  'contextmenu',
+  'mousewheel',
+  'DOMMouseScroll',
+  'mouseover',
+  'mouseout',
+  'mousemove',
+  'selectstart',
+  'selectend',
+  'keydown',
+  'keypress',
+  'keyup',
+  'orientationchange',
+  'touchstart',
+  'touchmove',
+  'touchend',
+  'touchcancel',
+  'pointerdown',
+  'pointermove',
+  'pointerup',
+  'pointerleave',
+  'pointercancel',
+  'gesturestart',
+  'gesturechange',
+  'gestureend',
+  'focus',
+  'blur',
+  'change',
+  'reset',
+  'select',
+  'submit',
+  'focusin',
+  'focusout',
+  'load',
+  'unload',
+  'beforeunload',
+  'resize',
+  'move',
+  'DOMContentLoaded',
+  'readystatechange',
+  'error',
+  'abort',
+  'scroll'
+])
+
+/**
+ * ------------------------------------------------------------------------
+ * Private methods
+ * ------------------------------------------------------------------------
+ */
+
+function getUidEvent(element, uid) {
+  return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++
+}
+
+function getEvent(element) {
+  const uid = getUidEvent(element)
+
+  element.uidEvent = uid
+  eventRegistry[uid] = eventRegistry[uid] || {}
+
+  return eventRegistry[uid]
+}
+
+function bootstrapHandler(element, fn) {
+  return function handler(event) {
+    event.delegateTarget = element
+
+    if (handler.oneOff) {
+      EventHandler.off(element, event.type, fn)
+    }
+
+    return fn.apply(element, [event])
+  }
+}
+
+function bootstrapDelegationHandler(element, selector, fn) {
+  return function handler(event) {
+    const domElements = element.querySelectorAll(selector)
+
+    for (let { target } = event; target && target !== this; target = target.parentNode) {
+      for (let i = domElements.length; i--;) {
+        if (domElements[i] === target) {
+          event.delegateTarget = target
+
+          if (handler.oneOff) {
+            EventHandler.off(element, event.type, selector, fn)
+          }
+
+          return fn.apply(target, [event])
+        }
+      }
+    }
+
+    // To please ESLint
+    return null
+  }
+}
+
+function findHandler(events, handler, delegationSelector = null) {
+  const uidEventList = Object.keys(events)
+
+  for (let i = 0, len = uidEventList.length; i < len; i++) {
+    const event = events[uidEventList[i]]
+
+    if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {
+      return event
+    }
+  }
+
+  return null
+}
+
+function normalizeParams(originalTypeEvent, handler, delegationFn) {
+  const delegation = typeof handler === 'string'
+  const originalHandler = delegation ? delegationFn : handler
+
+  let typeEvent = getTypeEvent(originalTypeEvent)
+  const isNative = nativeEvents.has(typeEvent)
+
+  if (!isNative) {
+    typeEvent = originalTypeEvent
+  }
+
+  return [delegation, originalHandler, typeEvent]
+}
+
+function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
+  if (typeof originalTypeEvent !== 'string' || !element) {
+    return
+  }
+
+  if (!handler) {
+    handler = delegationFn
+    delegationFn = null
+  }
+
+  // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
+  // this prevents the handler from being dispatched the same way as mouseover or mouseout does
+  if (customEventsRegex.test(originalTypeEvent)) {
+    const wrapFn = fn => {
+      return function (event) {
+        if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) {
+          return fn.call(this, event)
+        }
+      }
+    }
+
+    if (delegationFn) {
+      delegationFn = wrapFn(delegationFn)
+    } else {
+      handler = wrapFn(handler)
+    }
+  }
+
+  const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn)
+  const events = getEvent(element)
+  const handlers = events[typeEvent] || (events[typeEvent] = {})
+  const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null)
+
+  if (previousFn) {
+    previousFn.oneOff = previousFn.oneOff && oneOff
+
+    return
+  }
+
+  const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''))
+  const fn = delegation ?
+    bootstrapDelegationHandler(element, handler, delegationFn) :
+    bootstrapHandler(element, handler)
+
+  fn.delegationSelector = delegation ? handler : null
+  fn.originalHandler = originalHandler
+  fn.oneOff = oneOff
+  fn.uidEvent = uid
+  handlers[uid] = fn
+
+  element.addEventListener(typeEvent, fn, delegation)
+}
+
+function removeHandler(element, events, typeEvent, handler, delegationSelector) {
+  const fn = findHandler(events[typeEvent], handler, delegationSelector)
+
+  if (!fn) {
+    return
+  }
+
+  element.removeEventListener(typeEvent, fn, Boolean(delegationSelector))
+  delete events[typeEvent][fn.uidEvent]
+}
+
+function removeNamespacedHandlers(element, events, typeEvent, namespace) {
+  const storeElementEvent = events[typeEvent] || {}
+
+  Object.keys(storeElementEvent).forEach(handlerKey => {
+    if (handlerKey.includes(namespace)) {
+      const event = storeElementEvent[handlerKey]
+
+      removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector)
+    }
+  })
+}
+
+function getTypeEvent(event) {
+  // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
+  event = event.replace(stripNameRegex, '')
+  return customEvents[event] || event
+}
+
+const EventHandler = {
+  on(element, event, handler, delegationFn) {
+    addHandler(element, event, handler, delegationFn, false)
+  },
+
+  one(element, event, handler, delegationFn) {
+    addHandler(element, event, handler, delegationFn, true)
+  },
+
+  off(element, originalTypeEvent, handler, delegationFn) {
+    if (typeof originalTypeEvent !== 'string' || !element) {
+      return
+    }
+
+    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn)
+    const inNamespace = typeEvent !== originalTypeEvent
+    const events = getEvent(element)
+    const isNamespace = originalTypeEvent.startsWith('.')
+
+    if (typeof originalHandler !== 'undefined') {
+      // Simplest case: handler is passed, remove that listener ONLY.
+      if (!events || !events[typeEvent]) {
+        return
+      }
+
+      removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null)
+      return
+    }
+
+    if (isNamespace) {
+      Object.keys(events).forEach(elementEvent => {
+        removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1))
+      })
+    }
+
+    const storeElementEvent = events[typeEvent] || {}
+    Object.keys(storeElementEvent).forEach(keyHandlers => {
+      const handlerKey = keyHandlers.replace(stripUidRegex, '')
+
+      if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
+        const event = storeElementEvent[keyHandlers]
+
+        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector)
+      }
+    })
+  },
+
+  trigger(element, event, args) {
+    if (typeof event !== 'string' || !element) {
+      return null
+    }
+
+    const $ = getjQuery()
+    const typeEvent = getTypeEvent(event)
+    const inNamespace = event !== typeEvent
+    const isNative = nativeEvents.has(typeEvent)
+
+    let jQueryEvent
+    let bubbles = true
+    let nativeDispatch = true
+    let defaultPrevented = false
+    let evt = null
+
+    if (inNamespace && $) {
+      jQueryEvent = $.Event(event, args)
+
+      $(element).trigger(jQueryEvent)
+      bubbles = !jQueryEvent.isPropagationStopped()
+      nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()
+      defaultPrevented = jQueryEvent.isDefaultPrevented()
+    }
+
+    if (isNative) {
+      evt = document.createEvent('HTMLEvents')
+      evt.initEvent(typeEvent, bubbles, true)
+    } else {
+      evt = new CustomEvent(event, {
+        bubbles,
+        cancelable: true
+      })
+    }
+
+    // merge custom information in our event
+    if (typeof args !== 'undefined') {
+      Object.keys(args).forEach(key => {
+        Object.defineProperty(evt, key, {
+          get() {
+            return args[key]
+          }
+        })
+      })
+    }
+
+    if (defaultPrevented) {
+      evt.preventDefault()
+    }
+
+    if (nativeDispatch) {
+      element.dispatchEvent(evt)
+    }
+
+    if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {
+      jQueryEvent.preventDefault()
+    }
+
+    return evt
+  }
+}
+
+export default EventHandler
Index: trip-planner-front/node_modules/bootstrap/js/src/dom/manipulator.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/dom/manipulator.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/dom/manipulator.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,80 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): dom/manipulator.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+function normalizeData(val) {
+  if (val === 'true') {
+    return true
+  }
+
+  if (val === 'false') {
+    return false
+  }
+
+  if (val === Number(val).toString()) {
+    return Number(val)
+  }
+
+  if (val === '' || val === 'null') {
+    return null
+  }
+
+  return val
+}
+
+function normalizeDataKey(key) {
+  return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)
+}
+
+const Manipulator = {
+  setDataAttribute(element, key, value) {
+    element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)
+  },
+
+  removeDataAttribute(element, key) {
+    element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)
+  },
+
+  getDataAttributes(element) {
+    if (!element) {
+      return {}
+    }
+
+    const attributes = {}
+
+    Object.keys(element.dataset)
+      .filter(key => key.startsWith('bs'))
+      .forEach(key => {
+        let pureKey = key.replace(/^bs/, '')
+        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)
+        attributes[pureKey] = normalizeData(element.dataset[key])
+      })
+
+    return attributes
+  },
+
+  getDataAttribute(element, key) {
+    return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))
+  },
+
+  offset(element) {
+    const rect = element.getBoundingClientRect()
+
+    return {
+      top: rect.top + window.pageYOffset,
+      left: rect.left + window.pageXOffset
+    }
+  },
+
+  position(element) {
+    return {
+      top: element.offsetTop,
+      left: element.offsetLeft
+    }
+  }
+}
+
+export default Manipulator
Index: trip-planner-front/node_modules/bootstrap/js/src/dom/selector-engine.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/dom/selector-engine.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/dom/selector-engine.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,92 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): dom/selector-engine.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+import { isDisabled, isVisible } from '../util/index'
+
+const NODE_TEXT = 3
+
+const SelectorEngine = {
+  find(selector, element = document.documentElement) {
+    return [].concat(...Element.prototype.querySelectorAll.call(element, selector))
+  },
+
+  findOne(selector, element = document.documentElement) {
+    return Element.prototype.querySelector.call(element, selector)
+  },
+
+  children(element, selector) {
+    return [].concat(...element.children)
+      .filter(child => child.matches(selector))
+  },
+
+  parents(element, selector) {
+    const parents = []
+
+    let ancestor = element.parentNode
+
+    while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
+      if (ancestor.matches(selector)) {
+        parents.push(ancestor)
+      }
+
+      ancestor = ancestor.parentNode
+    }
+
+    return parents
+  },
+
+  prev(element, selector) {
+    let previous = element.previousElementSibling
+
+    while (previous) {
+      if (previous.matches(selector)) {
+        return [previous]
+      }
+
+      previous = previous.previousElementSibling
+    }
+
+    return []
+  },
+
+  next(element, selector) {
+    let next = element.nextElementSibling
+
+    while (next) {
+      if (next.matches(selector)) {
+        return [next]
+      }
+
+      next = next.nextElementSibling
+    }
+
+    return []
+  },
+
+  focusableChildren(element) {
+    const focusables = [
+      'a',
+      'button',
+      'input',
+      'textarea',
+      'select',
+      'details',
+      '[tabindex]',
+      '[contenteditable="true"]'
+    ].map(selector => `${selector}:not([tabindex^="-"])`).join(', ')
+
+    return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))
+  }
+}
+
+export default SelectorEngine
Index: trip-planner-front/node_modules/bootstrap/js/src/dropdown.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/dropdown.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/dropdown.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,499 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import * as Popper from '@popperjs/core'
+
+import {
+  defineJQueryPlugin,
+  getElement,
+  getElementFromSelector,
+  getNextActiveElement,
+  isDisabled,
+  isElement,
+  isRTL,
+  isVisible,
+  noop,
+  typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'dropdown'
+const DATA_KEY = 'bs.dropdown'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const ESCAPE_KEY = 'Escape'
+const SPACE_KEY = 'Space'
+const TAB_KEY = 'Tab'
+const ARROW_UP_KEY = 'ArrowUp'
+const ARROW_DOWN_KEY = 'ArrowDown'
+const RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button
+
+const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`)
+
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_DROPUP = 'dropup'
+const CLASS_NAME_DROPEND = 'dropend'
+const CLASS_NAME_DROPSTART = 'dropstart'
+const CLASS_NAME_NAVBAR = 'navbar'
+
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]'
+const SELECTOR_MENU = '.dropdown-menu'
+const SELECTOR_NAVBAR_NAV = '.navbar-nav'
+const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
+
+const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'
+const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'
+const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'
+const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'
+const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'
+const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'
+
+const Default = {
+  offset: [0, 2],
+  boundary: 'clippingParents',
+  reference: 'toggle',
+  display: 'dynamic',
+  popperConfig: null,
+  autoClose: true
+}
+
+const DefaultType = {
+  offset: '(array|string|function)',
+  boundary: '(string|element)',
+  reference: '(string|element|object)',
+  display: 'string',
+  popperConfig: '(null|object|function)',
+  autoClose: '(boolean|string)'
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Dropdown extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._popper = null
+    this._config = this._getConfig(config)
+    this._menu = this._getMenuElement()
+    this._inNavbar = this._detectNavbar()
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  toggle() {
+    return this._isShown() ? this.hide() : this.show()
+  }
+
+  show() {
+    if (isDisabled(this._element) || this._isShown(this._menu)) {
+      return
+    }
+
+    const relatedTarget = {
+      relatedTarget: this._element
+    }
+
+    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget)
+
+    if (showEvent.defaultPrevented) {
+      return
+    }
+
+    const parent = Dropdown.getParentFromElement(this._element)
+    // Totally disable Popper for Dropdowns in Navbar
+    if (this._inNavbar) {
+      Manipulator.setDataAttribute(this._menu, 'popper', 'none')
+    } else {
+      this._createPopper(parent)
+    }
+
+    // If this is a touch-enabled device we add extra
+    // empty mouseover listeners to the body's immediate children;
+    // only needed because of broken event delegation on iOS
+    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+    if ('ontouchstart' in document.documentElement &&
+      !parent.closest(SELECTOR_NAVBAR_NAV)) {
+      [].concat(...document.body.children)
+        .forEach(elem => EventHandler.on(elem, 'mouseover', noop))
+    }
+
+    this._element.focus()
+    this._element.setAttribute('aria-expanded', true)
+
+    this._menu.classList.add(CLASS_NAME_SHOW)
+    this._element.classList.add(CLASS_NAME_SHOW)
+    EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget)
+  }
+
+  hide() {
+    if (isDisabled(this._element) || !this._isShown(this._menu)) {
+      return
+    }
+
+    const relatedTarget = {
+      relatedTarget: this._element
+    }
+
+    this._completeHide(relatedTarget)
+  }
+
+  dispose() {
+    if (this._popper) {
+      this._popper.destroy()
+    }
+
+    super.dispose()
+  }
+
+  update() {
+    this._inNavbar = this._detectNavbar()
+    if (this._popper) {
+      this._popper.update()
+    }
+  }
+
+  // Private
+
+  _completeHide(relatedTarget) {
+    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    // If this is a touch-enabled device we remove the extra
+    // empty mouseover listeners we added for iOS support
+    if ('ontouchstart' in document.documentElement) {
+      [].concat(...document.body.children)
+        .forEach(elem => EventHandler.off(elem, 'mouseover', noop))
+    }
+
+    if (this._popper) {
+      this._popper.destroy()
+    }
+
+    this._menu.classList.remove(CLASS_NAME_SHOW)
+    this._element.classList.remove(CLASS_NAME_SHOW)
+    this._element.setAttribute('aria-expanded', 'false')
+    Manipulator.removeDataAttribute(this._menu, 'popper')
+    EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)
+  }
+
+  _getConfig(config) {
+    config = {
+      ...this.constructor.Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...config
+    }
+
+    typeCheckConfig(NAME, config, this.constructor.DefaultType)
+
+    if (typeof config.reference === 'object' && !isElement(config.reference) &&
+      typeof config.reference.getBoundingClientRect !== 'function'
+    ) {
+      // Popper virtual elements require a getBoundingClientRect method
+      throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`)
+    }
+
+    return config
+  }
+
+  _createPopper(parent) {
+    if (typeof Popper === 'undefined') {
+      throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)')
+    }
+
+    let referenceElement = this._element
+
+    if (this._config.reference === 'parent') {
+      referenceElement = parent
+    } else if (isElement(this._config.reference)) {
+      referenceElement = getElement(this._config.reference)
+    } else if (typeof this._config.reference === 'object') {
+      referenceElement = this._config.reference
+    }
+
+    const popperConfig = this._getPopperConfig()
+    const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false)
+
+    this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)
+
+    if (isDisplayStatic) {
+      Manipulator.setDataAttribute(this._menu, 'popper', 'static')
+    }
+  }
+
+  _isShown(element = this._element) {
+    return element.classList.contains(CLASS_NAME_SHOW)
+  }
+
+  _getMenuElement() {
+    return SelectorEngine.next(this._element, SELECTOR_MENU)[0]
+  }
+
+  _getPlacement() {
+    const parentDropdown = this._element.parentNode
+
+    if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
+      return PLACEMENT_RIGHT
+    }
+
+    if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
+      return PLACEMENT_LEFT
+    }
+
+    // We need to trim the value because custom properties can also include spaces
+    const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'
+
+    if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
+      return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP
+    }
+
+    return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM
+  }
+
+  _detectNavbar() {
+    return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null
+  }
+
+  _getOffset() {
+    const { offset } = this._config
+
+    if (typeof offset === 'string') {
+      return offset.split(',').map(val => Number.parseInt(val, 10))
+    }
+
+    if (typeof offset === 'function') {
+      return popperData => offset(popperData, this._element)
+    }
+
+    return offset
+  }
+
+  _getPopperConfig() {
+    const defaultBsPopperConfig = {
+      placement: this._getPlacement(),
+      modifiers: [{
+        name: 'preventOverflow',
+        options: {
+          boundary: this._config.boundary
+        }
+      },
+      {
+        name: 'offset',
+        options: {
+          offset: this._getOffset()
+        }
+      }]
+    }
+
+    // Disable Popper if we have a static display
+    if (this._config.display === 'static') {
+      defaultBsPopperConfig.modifiers = [{
+        name: 'applyStyles',
+        enabled: false
+      }]
+    }
+
+    return {
+      ...defaultBsPopperConfig,
+      ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
+    }
+  }
+
+  _selectMenuItem({ key, target }) {
+    const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible)
+
+    if (!items.length) {
+      return
+    }
+
+    // if target isn't included in items (e.g. when expanding the dropdown)
+    // allow cycling to get the last item in case key equals ARROW_UP_KEY
+    getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Dropdown.getOrCreateInstance(this, config)
+
+      if (typeof config !== 'string') {
+        return
+      }
+
+      if (typeof data[config] === 'undefined') {
+        throw new TypeError(`No method named "${config}"`)
+      }
+
+      data[config]()
+    })
+  }
+
+  static clearMenus(event) {
+    if (event && (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY))) {
+      return
+    }
+
+    const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE)
+
+    for (let i = 0, len = toggles.length; i < len; i++) {
+      const context = Dropdown.getInstance(toggles[i])
+      if (!context || context._config.autoClose === false) {
+        continue
+      }
+
+      if (!context._isShown()) {
+        continue
+      }
+
+      const relatedTarget = {
+        relatedTarget: context._element
+      }
+
+      if (event) {
+        const composedPath = event.composedPath()
+        const isMenuTarget = composedPath.includes(context._menu)
+        if (
+          composedPath.includes(context._element) ||
+          (context._config.autoClose === 'inside' && !isMenuTarget) ||
+          (context._config.autoClose === 'outside' && isMenuTarget)
+        ) {
+          continue
+        }
+
+        // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
+        if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {
+          continue
+        }
+
+        if (event.type === 'click') {
+          relatedTarget.clickEvent = event
+        }
+      }
+
+      context._completeHide(relatedTarget)
+    }
+  }
+
+  static getParentFromElement(element) {
+    return getElementFromSelector(element) || element.parentNode
+  }
+
+  static dataApiKeydownHandler(event) {
+    // If not input/textarea:
+    //  - And not a key in REGEXP_KEYDOWN => not a dropdown command
+    // If input/textarea:
+    //  - If space key => not a dropdown command
+    //  - If key is other than escape
+    //    - If key is not up or down => not a dropdown command
+    //    - If trigger inside the menu => not a dropdown command
+    if (/input|textarea/i.test(event.target.tagName) ?
+      event.key === SPACE_KEY || (event.key !== ESCAPE_KEY &&
+      ((event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY) ||
+        event.target.closest(SELECTOR_MENU))) :
+      !REGEXP_KEYDOWN.test(event.key)) {
+      return
+    }
+
+    const isActive = this.classList.contains(CLASS_NAME_SHOW)
+
+    if (!isActive && event.key === ESCAPE_KEY) {
+      return
+    }
+
+    event.preventDefault()
+    event.stopPropagation()
+
+    if (isDisabled(this)) {
+      return
+    }
+
+    const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]
+    const instance = Dropdown.getOrCreateInstance(getToggleButton)
+
+    if (event.key === ESCAPE_KEY) {
+      instance.hide()
+      return
+    }
+
+    if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
+      if (!isActive) {
+        instance.show()
+      }
+
+      instance._selectMenuItem(event)
+      return
+    }
+
+    if (!isActive || event.key === SPACE_KEY) {
+      Dropdown.clearMenus()
+    }
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)
+EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)
+EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)
+EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+  event.preventDefault()
+  Dropdown.getOrCreateInstance(this).toggle()
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Dropdown to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Dropdown)
+
+export default Dropdown
Index: trip-planner-front/node_modules/bootstrap/js/src/modal.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/modal.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/modal.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,437 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): modal.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElementFromSelector,
+  isRTL,
+  isVisible,
+  reflow,
+  typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import ScrollBarHelper from './util/scrollbar'
+import BaseComponent from './base-component'
+import Backdrop from './util/backdrop'
+import FocusTrap from './util/focustrap'
+import { enableDismissTrigger } from './util/component-functions'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'modal'
+const DATA_KEY = 'bs.modal'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+const ESCAPE_KEY = 'Escape'
+
+const Default = {
+  backdrop: true,
+  keyboard: true,
+  focus: true
+}
+
+const DefaultType = {
+  backdrop: '(boolean|string)',
+  keyboard: 'boolean',
+  focus: 'boolean'
+}
+
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_RESIZE = `resize${EVENT_KEY}`
+const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
+const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
+const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
+const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_OPEN = 'modal-open'
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_STATIC = 'modal-static'
+
+const OPEN_SELECTOR = '.modal.show'
+const SELECTOR_DIALOG = '.modal-dialog'
+const SELECTOR_MODAL_BODY = '.modal-body'
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Modal extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._config = this._getConfig(config)
+    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
+    this._backdrop = this._initializeBackDrop()
+    this._focustrap = this._initializeFocusTrap()
+    this._isShown = false
+    this._ignoreBackdropClick = false
+    this._isTransitioning = false
+    this._scrollBar = new ScrollBarHelper()
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  toggle(relatedTarget) {
+    return this._isShown ? this.hide() : this.show(relatedTarget)
+  }
+
+  show(relatedTarget) {
+    if (this._isShown || this._isTransitioning) {
+      return
+    }
+
+    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
+      relatedTarget
+    })
+
+    if (showEvent.defaultPrevented) {
+      return
+    }
+
+    this._isShown = true
+
+    if (this._isAnimated()) {
+      this._isTransitioning = true
+    }
+
+    this._scrollBar.hide()
+
+    document.body.classList.add(CLASS_NAME_OPEN)
+
+    this._adjustDialog()
+
+    this._setEscapeEvent()
+    this._setResizeEvent()
+
+    EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
+      EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
+        if (event.target === this._element) {
+          this._ignoreBackdropClick = true
+        }
+      })
+    })
+
+    this._showBackdrop(() => this._showElement(relatedTarget))
+  }
+
+  hide() {
+    if (!this._isShown || this._isTransitioning) {
+      return
+    }
+
+    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
+
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    this._isShown = false
+    const isAnimated = this._isAnimated()
+
+    if (isAnimated) {
+      this._isTransitioning = true
+    }
+
+    this._setEscapeEvent()
+    this._setResizeEvent()
+
+    this._focustrap.deactivate()
+
+    this._element.classList.remove(CLASS_NAME_SHOW)
+
+    EventHandler.off(this._element, EVENT_CLICK_DISMISS)
+    EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS)
+
+    this._queueCallback(() => this._hideModal(), this._element, isAnimated)
+  }
+
+  dispose() {
+    [window, this._dialog]
+      .forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY))
+
+    this._backdrop.dispose()
+    this._focustrap.deactivate()
+    super.dispose()
+  }
+
+  handleUpdate() {
+    this._adjustDialog()
+  }
+
+  // Private
+
+  _initializeBackDrop() {
+    return new Backdrop({
+      isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value
+      isAnimated: this._isAnimated()
+    })
+  }
+
+  _initializeFocusTrap() {
+    return new FocusTrap({
+      trapElement: this._element
+    })
+  }
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...(typeof config === 'object' ? config : {})
+    }
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+
+  _showElement(relatedTarget) {
+    const isAnimated = this._isAnimated()
+    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
+
+    if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+      // Don't move modal's DOM position
+      document.body.append(this._element)
+    }
+
+    this._element.style.display = 'block'
+    this._element.removeAttribute('aria-hidden')
+    this._element.setAttribute('aria-modal', true)
+    this._element.setAttribute('role', 'dialog')
+    this._element.scrollTop = 0
+
+    if (modalBody) {
+      modalBody.scrollTop = 0
+    }
+
+    if (isAnimated) {
+      reflow(this._element)
+    }
+
+    this._element.classList.add(CLASS_NAME_SHOW)
+
+    const transitionComplete = () => {
+      if (this._config.focus) {
+        this._focustrap.activate()
+      }
+
+      this._isTransitioning = false
+      EventHandler.trigger(this._element, EVENT_SHOWN, {
+        relatedTarget
+      })
+    }
+
+    this._queueCallback(transitionComplete, this._dialog, isAnimated)
+  }
+
+  _setEscapeEvent() {
+    if (this._isShown) {
+      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
+        if (this._config.keyboard && event.key === ESCAPE_KEY) {
+          event.preventDefault()
+          this.hide()
+        } else if (!this._config.keyboard && event.key === ESCAPE_KEY) {
+          this._triggerBackdropTransition()
+        }
+      })
+    } else {
+      EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS)
+    }
+  }
+
+  _setResizeEvent() {
+    if (this._isShown) {
+      EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog())
+    } else {
+      EventHandler.off(window, EVENT_RESIZE)
+    }
+  }
+
+  _hideModal() {
+    this._element.style.display = 'none'
+    this._element.setAttribute('aria-hidden', true)
+    this._element.removeAttribute('aria-modal')
+    this._element.removeAttribute('role')
+    this._isTransitioning = false
+    this._backdrop.hide(() => {
+      document.body.classList.remove(CLASS_NAME_OPEN)
+      this._resetAdjustments()
+      this._scrollBar.reset()
+      EventHandler.trigger(this._element, EVENT_HIDDEN)
+    })
+  }
+
+  _showBackdrop(callback) {
+    EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {
+      if (this._ignoreBackdropClick) {
+        this._ignoreBackdropClick = false
+        return
+      }
+
+      if (event.target !== event.currentTarget) {
+        return
+      }
+
+      if (this._config.backdrop === true) {
+        this.hide()
+      } else if (this._config.backdrop === 'static') {
+        this._triggerBackdropTransition()
+      }
+    })
+
+    this._backdrop.show(callback)
+  }
+
+  _isAnimated() {
+    return this._element.classList.contains(CLASS_NAME_FADE)
+  }
+
+  _triggerBackdropTransition() {
+    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    const { classList, scrollHeight, style } = this._element
+    const isModalOverflowing = scrollHeight > document.documentElement.clientHeight
+
+    // return if the following background transition hasn't yet completed
+    if ((!isModalOverflowing && style.overflowY === 'hidden') || classList.contains(CLASS_NAME_STATIC)) {
+      return
+    }
+
+    if (!isModalOverflowing) {
+      style.overflowY = 'hidden'
+    }
+
+    classList.add(CLASS_NAME_STATIC)
+    this._queueCallback(() => {
+      classList.remove(CLASS_NAME_STATIC)
+      if (!isModalOverflowing) {
+        this._queueCallback(() => {
+          style.overflowY = ''
+        }, this._dialog)
+      }
+    }, this._dialog)
+
+    this._element.focus()
+  }
+
+  // ----------------------------------------------------------------------
+  // the following methods are used to handle overflowing modals
+  // ----------------------------------------------------------------------
+
+  _adjustDialog() {
+    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
+    const scrollbarWidth = this._scrollBar.getWidth()
+    const isBodyOverflowing = scrollbarWidth > 0
+
+    if ((!isBodyOverflowing && isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && isRTL())) {
+      this._element.style.paddingLeft = `${scrollbarWidth}px`
+    }
+
+    if ((isBodyOverflowing && !isModalOverflowing && !isRTL()) || (!isBodyOverflowing && isModalOverflowing && isRTL())) {
+      this._element.style.paddingRight = `${scrollbarWidth}px`
+    }
+  }
+
+  _resetAdjustments() {
+    this._element.style.paddingLeft = ''
+    this._element.style.paddingRight = ''
+  }
+
+  // Static
+
+  static jQueryInterface(config, relatedTarget) {
+    return this.each(function () {
+      const data = Modal.getOrCreateInstance(this, config)
+
+      if (typeof config !== 'string') {
+        return
+      }
+
+      if (typeof data[config] === 'undefined') {
+        throw new TypeError(`No method named "${config}"`)
+      }
+
+      data[config](relatedTarget)
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+  const target = getElementFromSelector(this)
+
+  if (['A', 'AREA'].includes(this.tagName)) {
+    event.preventDefault()
+  }
+
+  EventHandler.one(target, EVENT_SHOW, showEvent => {
+    if (showEvent.defaultPrevented) {
+      // only register focus restorer if modal will actually get shown
+      return
+    }
+
+    EventHandler.one(target, EVENT_HIDDEN, () => {
+      if (isVisible(this)) {
+        this.focus()
+      }
+    })
+  })
+
+  // avoid conflict when clicking moddal toggler while another one is open
+  const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)
+  if (allReadyOpen) {
+    Modal.getInstance(allReadyOpen).hide()
+  }
+
+  const data = Modal.getOrCreateInstance(target)
+
+  data.toggle(this)
+})
+
+enableDismissTrigger(Modal)
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Modal to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Modal)
+
+export default Modal
Index: trip-planner-front/node_modules/bootstrap/js/src/offcanvas.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/offcanvas.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/offcanvas.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,272 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): offcanvas.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElementFromSelector,
+  isDisabled,
+  isVisible,
+  typeCheckConfig
+} from './util/index'
+import ScrollBarHelper from './util/scrollbar'
+import EventHandler from './dom/event-handler'
+import BaseComponent from './base-component'
+import SelectorEngine from './dom/selector-engine'
+import Manipulator from './dom/manipulator'
+import Backdrop from './util/backdrop'
+import FocusTrap from './util/focustrap'
+import { enableDismissTrigger } from './util/component-functions'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'offcanvas'
+const DATA_KEY = 'bs.offcanvas'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
+const ESCAPE_KEY = 'Escape'
+
+const Default = {
+  backdrop: true,
+  keyboard: true,
+  scroll: false
+}
+
+const DefaultType = {
+  backdrop: 'boolean',
+  keyboard: 'boolean',
+  scroll: 'boolean'
+}
+
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'
+const OPEN_SELECTOR = '.offcanvas.show'
+
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
+
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Offcanvas extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._config = this._getConfig(config)
+    this._isShown = false
+    this._backdrop = this._initializeBackDrop()
+    this._focustrap = this._initializeFocusTrap()
+    this._addEventListeners()
+  }
+
+  // Getters
+
+  static get NAME() {
+    return NAME
+  }
+
+  static get Default() {
+    return Default
+  }
+
+  // Public
+
+  toggle(relatedTarget) {
+    return this._isShown ? this.hide() : this.show(relatedTarget)
+  }
+
+  show(relatedTarget) {
+    if (this._isShown) {
+      return
+    }
+
+    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget })
+
+    if (showEvent.defaultPrevented) {
+      return
+    }
+
+    this._isShown = true
+    this._element.style.visibility = 'visible'
+
+    this._backdrop.show()
+
+    if (!this._config.scroll) {
+      new ScrollBarHelper().hide()
+    }
+
+    this._element.removeAttribute('aria-hidden')
+    this._element.setAttribute('aria-modal', true)
+    this._element.setAttribute('role', 'dialog')
+    this._element.classList.add(CLASS_NAME_SHOW)
+
+    const completeCallBack = () => {
+      if (!this._config.scroll) {
+        this._focustrap.activate()
+      }
+
+      EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })
+    }
+
+    this._queueCallback(completeCallBack, this._element, true)
+  }
+
+  hide() {
+    if (!this._isShown) {
+      return
+    }
+
+    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
+
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    this._focustrap.deactivate()
+    this._element.blur()
+    this._isShown = false
+    this._element.classList.remove(CLASS_NAME_SHOW)
+    this._backdrop.hide()
+
+    const completeCallback = () => {
+      this._element.setAttribute('aria-hidden', true)
+      this._element.removeAttribute('aria-modal')
+      this._element.removeAttribute('role')
+      this._element.style.visibility = 'hidden'
+
+      if (!this._config.scroll) {
+        new ScrollBarHelper().reset()
+      }
+
+      EventHandler.trigger(this._element, EVENT_HIDDEN)
+    }
+
+    this._queueCallback(completeCallback, this._element, true)
+  }
+
+  dispose() {
+    this._backdrop.dispose()
+    this._focustrap.deactivate()
+    super.dispose()
+  }
+
+  // Private
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...(typeof config === 'object' ? config : {})
+    }
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+
+  _initializeBackDrop() {
+    return new Backdrop({
+      className: CLASS_NAME_BACKDROP,
+      isVisible: this._config.backdrop,
+      isAnimated: true,
+      rootElement: this._element.parentNode,
+      clickCallback: () => this.hide()
+    })
+  }
+
+  _initializeFocusTrap() {
+    return new FocusTrap({
+      trapElement: this._element
+    })
+  }
+
+  _addEventListeners() {
+    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
+      if (this._config.keyboard && event.key === ESCAPE_KEY) {
+        this.hide()
+      }
+    })
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Offcanvas.getOrCreateInstance(this, config)
+
+      if (typeof config !== 'string') {
+        return
+      }
+
+      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
+        throw new TypeError(`No method named "${config}"`)
+      }
+
+      data[config](this)
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+  const target = getElementFromSelector(this)
+
+  if (['A', 'AREA'].includes(this.tagName)) {
+    event.preventDefault()
+  }
+
+  if (isDisabled(this)) {
+    return
+  }
+
+  EventHandler.one(target, EVENT_HIDDEN, () => {
+    // focus on trigger when it is closed
+    if (isVisible(this)) {
+      this.focus()
+    }
+  })
+
+  // avoid conflict when clicking a toggler of an offcanvas, while another is open
+  const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)
+  if (allReadyOpen && allReadyOpen !== target) {
+    Offcanvas.getInstance(allReadyOpen).hide()
+  }
+
+  const data = Offcanvas.getOrCreateInstance(target)
+  data.toggle(this)
+})
+
+EventHandler.on(window, EVENT_LOAD_DATA_API, () =>
+  SelectorEngine.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show())
+)
+
+enableDismissTrigger(Offcanvas)
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+defineJQueryPlugin(Offcanvas)
+
+export default Offcanvas
Index: trip-planner-front/node_modules/bootstrap/js/src/popover.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/popover.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/popover.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,128 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import { defineJQueryPlugin } from './util/index'
+import Tooltip from './tooltip'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'popover'
+const DATA_KEY = 'bs.popover'
+const EVENT_KEY = `.${DATA_KEY}`
+const CLASS_PREFIX = 'bs-popover'
+
+const Default = {
+  ...Tooltip.Default,
+  placement: 'right',
+  offset: [0, 8],
+  trigger: 'click',
+  content: '',
+  template: '<div class="popover" role="tooltip">' +
+              '<div class="popover-arrow"></div>' +
+              '<h3 class="popover-header"></h3>' +
+              '<div class="popover-body"></div>' +
+            '</div>'
+}
+
+const DefaultType = {
+  ...Tooltip.DefaultType,
+  content: '(string|element|function)'
+}
+
+const Event = {
+  HIDE: `hide${EVENT_KEY}`,
+  HIDDEN: `hidden${EVENT_KEY}`,
+  SHOW: `show${EVENT_KEY}`,
+  SHOWN: `shown${EVENT_KEY}`,
+  INSERTED: `inserted${EVENT_KEY}`,
+  CLICK: `click${EVENT_KEY}`,
+  FOCUSIN: `focusin${EVENT_KEY}`,
+  FOCUSOUT: `focusout${EVENT_KEY}`,
+  MOUSEENTER: `mouseenter${EVENT_KEY}`,
+  MOUSELEAVE: `mouseleave${EVENT_KEY}`
+}
+
+const SELECTOR_TITLE = '.popover-header'
+const SELECTOR_CONTENT = '.popover-body'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Popover extends Tooltip {
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  static get Event() {
+    return Event
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  // Overrides
+
+  isWithContent() {
+    return this.getTitle() || this._getContent()
+  }
+
+  setContent(tip) {
+    this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE)
+    this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT)
+  }
+
+  // Private
+
+  _getContent() {
+    return this._resolvePossibleFunction(this._config.content)
+  }
+
+  _getBasicClassPrefix() {
+    return CLASS_PREFIX
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Popover.getOrCreateInstance(this, config)
+
+      if (typeof config === 'string') {
+        if (typeof data[config] === 'undefined') {
+          throw new TypeError(`No method named "${config}"`)
+        }
+
+        data[config]()
+      }
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Popover to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Popover)
+
+export default Popover
Index: trip-planner-front/node_modules/bootstrap/js/src/scrollspy.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/scrollspy.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/scrollspy.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,295 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElement,
+  getSelectorFromElement,
+  typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'scrollspy'
+const DATA_KEY = 'bs.scrollspy'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const Default = {
+  offset: 10,
+  method: 'auto',
+  target: ''
+}
+
+const DefaultType = {
+  offset: 'number',
+  method: 'string',
+  target: '(string|element)'
+}
+
+const EVENT_ACTIVATE = `activate${EVENT_KEY}`
+const EVENT_SCROLL = `scroll${EVENT_KEY}`
+const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'
+const CLASS_NAME_ACTIVE = 'active'
+
+const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'
+const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
+const SELECTOR_NAV_LINKS = '.nav-link'
+const SELECTOR_NAV_ITEMS = '.nav-item'
+const SELECTOR_LIST_ITEMS = '.list-group-item'
+const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`
+const SELECTOR_DROPDOWN = '.dropdown'
+const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
+
+const METHOD_OFFSET = 'offset'
+const METHOD_POSITION = 'position'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class ScrollSpy extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+    this._scrollElement = this._element.tagName === 'BODY' ? window : this._element
+    this._config = this._getConfig(config)
+    this._offsets = []
+    this._targets = []
+    this._activeTarget = null
+    this._scrollHeight = 0
+
+    EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process())
+
+    this.refresh()
+    this._process()
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  refresh() {
+    const autoMethod = this._scrollElement === this._scrollElement.window ?
+      METHOD_OFFSET :
+      METHOD_POSITION
+
+    const offsetMethod = this._config.method === 'auto' ?
+      autoMethod :
+      this._config.method
+
+    const offsetBase = offsetMethod === METHOD_POSITION ?
+      this._getScrollTop() :
+      0
+
+    this._offsets = []
+    this._targets = []
+    this._scrollHeight = this._getScrollHeight()
+
+    const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
+
+    targets.map(element => {
+      const targetSelector = getSelectorFromElement(element)
+      const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null
+
+      if (target) {
+        const targetBCR = target.getBoundingClientRect()
+        if (targetBCR.width || targetBCR.height) {
+          return [
+            Manipulator[offsetMethod](target).top + offsetBase,
+            targetSelector
+          ]
+        }
+      }
+
+      return null
+    })
+      .filter(item => item)
+      .sort((a, b) => a[0] - b[0])
+      .forEach(item => {
+        this._offsets.push(item[0])
+        this._targets.push(item[1])
+      })
+  }
+
+  dispose() {
+    EventHandler.off(this._scrollElement, EVENT_KEY)
+    super.dispose()
+  }
+
+  // Private
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...(typeof config === 'object' && config ? config : {})
+    }
+
+    config.target = getElement(config.target) || document.documentElement
+
+    typeCheckConfig(NAME, config, DefaultType)
+
+    return config
+  }
+
+  _getScrollTop() {
+    return this._scrollElement === window ?
+      this._scrollElement.pageYOffset :
+      this._scrollElement.scrollTop
+  }
+
+  _getScrollHeight() {
+    return this._scrollElement.scrollHeight || Math.max(
+      document.body.scrollHeight,
+      document.documentElement.scrollHeight
+    )
+  }
+
+  _getOffsetHeight() {
+    return this._scrollElement === window ?
+      window.innerHeight :
+      this._scrollElement.getBoundingClientRect().height
+  }
+
+  _process() {
+    const scrollTop = this._getScrollTop() + this._config.offset
+    const scrollHeight = this._getScrollHeight()
+    const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight()
+
+    if (this._scrollHeight !== scrollHeight) {
+      this.refresh()
+    }
+
+    if (scrollTop >= maxScroll) {
+      const target = this._targets[this._targets.length - 1]
+
+      if (this._activeTarget !== target) {
+        this._activate(target)
+      }
+
+      return
+    }
+
+    if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
+      this._activeTarget = null
+      this._clear()
+      return
+    }
+
+    for (let i = this._offsets.length; i--;) {
+      const isActiveTarget = this._activeTarget !== this._targets[i] &&
+          scrollTop >= this._offsets[i] &&
+          (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1])
+
+      if (isActiveTarget) {
+        this._activate(this._targets[i])
+      }
+    }
+  }
+
+  _activate(target) {
+    this._activeTarget = target
+
+    this._clear()
+
+    const queries = SELECTOR_LINK_ITEMS.split(',')
+      .map(selector => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`)
+
+    const link = SelectorEngine.findOne(queries.join(','), this._config.target)
+
+    link.classList.add(CLASS_NAME_ACTIVE)
+    if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
+      SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN))
+        .classList.add(CLASS_NAME_ACTIVE)
+    } else {
+      SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP)
+        .forEach(listGroup => {
+          // Set triggered links parents as active
+          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
+          SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)
+            .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
+
+          // Handle special case when .nav-link is inside .nav-item
+          SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS)
+            .forEach(navItem => {
+              SelectorEngine.children(navItem, SELECTOR_NAV_LINKS)
+                .forEach(item => item.classList.add(CLASS_NAME_ACTIVE))
+            })
+        })
+    }
+
+    EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {
+      relatedTarget: target
+    })
+  }
+
+  _clear() {
+    SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
+      .filter(node => node.classList.contains(CLASS_NAME_ACTIVE))
+      .forEach(node => node.classList.remove(CLASS_NAME_ACTIVE))
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = ScrollSpy.getOrCreateInstance(this, config)
+
+      if (typeof config !== 'string') {
+        return
+      }
+
+      if (typeof data[config] === 'undefined') {
+        throw new TypeError(`No method named "${config}"`)
+      }
+
+      data[config]()
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
+  SelectorEngine.find(SELECTOR_DATA_SPY)
+    .forEach(spy => new ScrollSpy(spy))
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .ScrollSpy to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(ScrollSpy)
+
+export default ScrollSpy
Index: trip-planner-front/node_modules/bootstrap/js/src/tab.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/tab.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/tab.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,224 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  getElementFromSelector,
+  isDisabled,
+  reflow
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'tab'
+const DATA_KEY = 'bs.tab'
+const EVENT_KEY = `.${DATA_KEY}`
+const DATA_API_KEY = '.data-api'
+
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
+
+const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
+const CLASS_NAME_ACTIVE = 'active'
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+
+const SELECTOR_DROPDOWN = '.dropdown'
+const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
+const SELECTOR_ACTIVE = '.active'
+const SELECTOR_ACTIVE_UL = ':scope > li > .active'
+const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'
+const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
+const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Tab extends BaseComponent {
+  // Getters
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  show() {
+    if ((this._element.parentNode &&
+      this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
+      this._element.classList.contains(CLASS_NAME_ACTIVE))) {
+      return
+    }
+
+    let previous
+    const target = getElementFromSelector(this._element)
+    const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP)
+
+    if (listElement) {
+      const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE
+      previous = SelectorEngine.find(itemSelector, listElement)
+      previous = previous[previous.length - 1]
+    }
+
+    const hideEvent = previous ?
+      EventHandler.trigger(previous, EVENT_HIDE, {
+        relatedTarget: this._element
+      }) :
+      null
+
+    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
+      relatedTarget: previous
+    })
+
+    if (showEvent.defaultPrevented || (hideEvent !== null && hideEvent.defaultPrevented)) {
+      return
+    }
+
+    this._activate(this._element, listElement)
+
+    const complete = () => {
+      EventHandler.trigger(previous, EVENT_HIDDEN, {
+        relatedTarget: this._element
+      })
+      EventHandler.trigger(this._element, EVENT_SHOWN, {
+        relatedTarget: previous
+      })
+    }
+
+    if (target) {
+      this._activate(target, target.parentNode, complete)
+    } else {
+      complete()
+    }
+  }
+
+  // Private
+
+  _activate(element, container, callback) {
+    const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
+      SelectorEngine.find(SELECTOR_ACTIVE_UL, container) :
+      SelectorEngine.children(container, SELECTOR_ACTIVE)
+
+    const active = activeElements[0]
+    const isTransitioning = callback && (active && active.classList.contains(CLASS_NAME_FADE))
+
+    const complete = () => this._transitionComplete(element, active, callback)
+
+    if (active && isTransitioning) {
+      active.classList.remove(CLASS_NAME_SHOW)
+      this._queueCallback(complete, element, true)
+    } else {
+      complete()
+    }
+  }
+
+  _transitionComplete(element, active, callback) {
+    if (active) {
+      active.classList.remove(CLASS_NAME_ACTIVE)
+
+      const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode)
+
+      if (dropdownChild) {
+        dropdownChild.classList.remove(CLASS_NAME_ACTIVE)
+      }
+
+      if (active.getAttribute('role') === 'tab') {
+        active.setAttribute('aria-selected', false)
+      }
+    }
+
+    element.classList.add(CLASS_NAME_ACTIVE)
+    if (element.getAttribute('role') === 'tab') {
+      element.setAttribute('aria-selected', true)
+    }
+
+    reflow(element)
+
+    if (element.classList.contains(CLASS_NAME_FADE)) {
+      element.classList.add(CLASS_NAME_SHOW)
+    }
+
+    let parent = element.parentNode
+    if (parent && parent.nodeName === 'LI') {
+      parent = parent.parentNode
+    }
+
+    if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
+      const dropdownElement = element.closest(SELECTOR_DROPDOWN)
+
+      if (dropdownElement) {
+        SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement)
+          .forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE))
+      }
+
+      element.setAttribute('aria-expanded', true)
+    }
+
+    if (callback) {
+      callback()
+    }
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Tab.getOrCreateInstance(this)
+
+      if (typeof config === 'string') {
+        if (typeof data[config] === 'undefined') {
+          throw new TypeError(`No method named "${config}"`)
+        }
+
+        data[config]()
+      }
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
+  if (['A', 'AREA'].includes(this.tagName)) {
+    event.preventDefault()
+  }
+
+  if (isDisabled(this)) {
+    return
+  }
+
+  const data = Tab.getOrCreateInstance(this)
+  data.show()
+})
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Tab to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Tab)
+
+export default Tab
Index: trip-planner-front/node_modules/bootstrap/js/src/toast.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/toast.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/toast.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,242 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): toast.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import {
+  defineJQueryPlugin,
+  reflow,
+  typeCheckConfig
+} from './util/index'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import BaseComponent from './base-component'
+import { enableDismissTrigger } from './util/component-functions'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'toast'
+const DATA_KEY = 'bs.toast'
+const EVENT_KEY = `.${DATA_KEY}`
+
+const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`
+const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`
+const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
+const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`
+const EVENT_HIDE = `hide${EVENT_KEY}`
+const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_SHOW = `show${EVENT_KEY}`
+const EVENT_SHOWN = `shown${EVENT_KEY}`
+
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_HIDE = 'hide' // @deprecated - kept here only for backwards compatibility
+const CLASS_NAME_SHOW = 'show'
+const CLASS_NAME_SHOWING = 'showing'
+
+const DefaultType = {
+  animation: 'boolean',
+  autohide: 'boolean',
+  delay: 'number'
+}
+
+const Default = {
+  animation: true,
+  autohide: true,
+  delay: 5000
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Toast extends BaseComponent {
+  constructor(element, config) {
+    super(element)
+
+    this._config = this._getConfig(config)
+    this._timeout = null
+    this._hasMouseInteraction = false
+    this._hasKeyboardInteraction = false
+    this._setListeners()
+  }
+
+  // Getters
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  // Public
+
+  show() {
+    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
+
+    if (showEvent.defaultPrevented) {
+      return
+    }
+
+    this._clearTimeout()
+
+    if (this._config.animation) {
+      this._element.classList.add(CLASS_NAME_FADE)
+    }
+
+    const complete = () => {
+      this._element.classList.remove(CLASS_NAME_SHOWING)
+      EventHandler.trigger(this._element, EVENT_SHOWN)
+
+      this._maybeScheduleHide()
+    }
+
+    this._element.classList.remove(CLASS_NAME_HIDE) // @deprecated
+    reflow(this._element)
+    this._element.classList.add(CLASS_NAME_SHOW)
+    this._element.classList.add(CLASS_NAME_SHOWING)
+
+    this._queueCallback(complete, this._element, this._config.animation)
+  }
+
+  hide() {
+    if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
+      return
+    }
+
+    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
+
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    const complete = () => {
+      this._element.classList.add(CLASS_NAME_HIDE) // @deprecated
+      this._element.classList.remove(CLASS_NAME_SHOWING)
+      this._element.classList.remove(CLASS_NAME_SHOW)
+      EventHandler.trigger(this._element, EVENT_HIDDEN)
+    }
+
+    this._element.classList.add(CLASS_NAME_SHOWING)
+    this._queueCallback(complete, this._element, this._config.animation)
+  }
+
+  dispose() {
+    this._clearTimeout()
+
+    if (this._element.classList.contains(CLASS_NAME_SHOW)) {
+      this._element.classList.remove(CLASS_NAME_SHOW)
+    }
+
+    super.dispose()
+  }
+
+  // Private
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...Manipulator.getDataAttributes(this._element),
+      ...(typeof config === 'object' && config ? config : {})
+    }
+
+    typeCheckConfig(NAME, config, this.constructor.DefaultType)
+
+    return config
+  }
+
+  _maybeScheduleHide() {
+    if (!this._config.autohide) {
+      return
+    }
+
+    if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
+      return
+    }
+
+    this._timeout = setTimeout(() => {
+      this.hide()
+    }, this._config.delay)
+  }
+
+  _onInteraction(event, isInteracting) {
+    switch (event.type) {
+      case 'mouseover':
+      case 'mouseout':
+        this._hasMouseInteraction = isInteracting
+        break
+      case 'focusin':
+      case 'focusout':
+        this._hasKeyboardInteraction = isInteracting
+        break
+      default:
+        break
+    }
+
+    if (isInteracting) {
+      this._clearTimeout()
+      return
+    }
+
+    const nextElement = event.relatedTarget
+    if (this._element === nextElement || this._element.contains(nextElement)) {
+      return
+    }
+
+    this._maybeScheduleHide()
+  }
+
+  _setListeners() {
+    EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true))
+    EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false))
+    EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true))
+    EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false))
+  }
+
+  _clearTimeout() {
+    clearTimeout(this._timeout)
+    this._timeout = null
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Toast.getOrCreateInstance(this, config)
+
+      if (typeof config === 'string') {
+        if (typeof data[config] === 'undefined') {
+          throw new TypeError(`No method named "${config}"`)
+        }
+
+        data[config](this)
+      }
+    })
+  }
+}
+
+enableDismissTrigger(Toast)
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Toast to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Toast)
+
+export default Toast
Index: trip-planner-front/node_modules/bootstrap/js/src/tooltip.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/tooltip.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/tooltip.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,763 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): tooltip.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import * as Popper from '@popperjs/core'
+
+import {
+  defineJQueryPlugin,
+  findShadowRoot,
+  getElement,
+  getUID,
+  isElement,
+  isRTL,
+  noop,
+  typeCheckConfig
+} from './util/index'
+import { DefaultAllowlist, sanitizeHtml } from './util/sanitizer'
+import Data from './dom/data'
+import EventHandler from './dom/event-handler'
+import Manipulator from './dom/manipulator'
+import SelectorEngine from './dom/selector-engine'
+import BaseComponent from './base-component'
+
+/**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+const NAME = 'tooltip'
+const DATA_KEY = 'bs.tooltip'
+const EVENT_KEY = `.${DATA_KEY}`
+const CLASS_PREFIX = 'bs-tooltip'
+const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])
+
+const DefaultType = {
+  animation: 'boolean',
+  template: 'string',
+  title: '(string|element|function)',
+  trigger: 'string',
+  delay: '(number|object)',
+  html: 'boolean',
+  selector: '(string|boolean)',
+  placement: '(string|function)',
+  offset: '(array|string|function)',
+  container: '(string|element|boolean)',
+  fallbackPlacements: 'array',
+  boundary: '(string|element)',
+  customClass: '(string|function)',
+  sanitize: 'boolean',
+  sanitizeFn: '(null|function)',
+  allowList: 'object',
+  popperConfig: '(null|object|function)'
+}
+
+const AttachmentMap = {
+  AUTO: 'auto',
+  TOP: 'top',
+  RIGHT: isRTL() ? 'left' : 'right',
+  BOTTOM: 'bottom',
+  LEFT: isRTL() ? 'right' : 'left'
+}
+
+const Default = {
+  animation: true,
+  template: '<div class="tooltip" role="tooltip">' +
+              '<div class="tooltip-arrow"></div>' +
+              '<div class="tooltip-inner"></div>' +
+            '</div>',
+  trigger: 'hover focus',
+  title: '',
+  delay: 0,
+  html: false,
+  selector: false,
+  placement: 'top',
+  offset: [0, 0],
+  container: false,
+  fallbackPlacements: ['top', 'right', 'bottom', 'left'],
+  boundary: 'clippingParents',
+  customClass: '',
+  sanitize: true,
+  sanitizeFn: null,
+  allowList: DefaultAllowlist,
+  popperConfig: null
+}
+
+const Event = {
+  HIDE: `hide${EVENT_KEY}`,
+  HIDDEN: `hidden${EVENT_KEY}`,
+  SHOW: `show${EVENT_KEY}`,
+  SHOWN: `shown${EVENT_KEY}`,
+  INSERTED: `inserted${EVENT_KEY}`,
+  CLICK: `click${EVENT_KEY}`,
+  FOCUSIN: `focusin${EVENT_KEY}`,
+  FOCUSOUT: `focusout${EVENT_KEY}`,
+  MOUSEENTER: `mouseenter${EVENT_KEY}`,
+  MOUSELEAVE: `mouseleave${EVENT_KEY}`
+}
+
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_MODAL = 'modal'
+const CLASS_NAME_SHOW = 'show'
+
+const HOVER_STATE_SHOW = 'show'
+const HOVER_STATE_OUT = 'out'
+
+const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'
+const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`
+
+const EVENT_MODAL_HIDE = 'hide.bs.modal'
+
+const TRIGGER_HOVER = 'hover'
+const TRIGGER_FOCUS = 'focus'
+const TRIGGER_CLICK = 'click'
+const TRIGGER_MANUAL = 'manual'
+
+/**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+class Tooltip extends BaseComponent {
+  constructor(element, config) {
+    if (typeof Popper === 'undefined') {
+      throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)')
+    }
+
+    super(element)
+
+    // private
+    this._isEnabled = true
+    this._timeout = 0
+    this._hoverState = ''
+    this._activeTrigger = {}
+    this._popper = null
+
+    // Protected
+    this._config = this._getConfig(config)
+    this.tip = null
+
+    this._setListeners()
+  }
+
+  // Getters
+
+  static get Default() {
+    return Default
+  }
+
+  static get NAME() {
+    return NAME
+  }
+
+  static get Event() {
+    return Event
+  }
+
+  static get DefaultType() {
+    return DefaultType
+  }
+
+  // Public
+
+  enable() {
+    this._isEnabled = true
+  }
+
+  disable() {
+    this._isEnabled = false
+  }
+
+  toggleEnabled() {
+    this._isEnabled = !this._isEnabled
+  }
+
+  toggle(event) {
+    if (!this._isEnabled) {
+      return
+    }
+
+    if (event) {
+      const context = this._initializeOnDelegatedTarget(event)
+
+      context._activeTrigger.click = !context._activeTrigger.click
+
+      if (context._isWithActiveTrigger()) {
+        context._enter(null, context)
+      } else {
+        context._leave(null, context)
+      }
+    } else {
+      if (this.getTipElement().classList.contains(CLASS_NAME_SHOW)) {
+        this._leave(null, this)
+        return
+      }
+
+      this._enter(null, this)
+    }
+  }
+
+  dispose() {
+    clearTimeout(this._timeout)
+
+    EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)
+
+    if (this.tip) {
+      this.tip.remove()
+    }
+
+    this._disposePopper()
+    super.dispose()
+  }
+
+  show() {
+    if (this._element.style.display === 'none') {
+      throw new Error('Please use show on visible elements')
+    }
+
+    if (!(this.isWithContent() && this._isEnabled)) {
+      return
+    }
+
+    const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW)
+    const shadowRoot = findShadowRoot(this._element)
+    const isInTheDom = shadowRoot === null ?
+      this._element.ownerDocument.documentElement.contains(this._element) :
+      shadowRoot.contains(this._element)
+
+    if (showEvent.defaultPrevented || !isInTheDom) {
+      return
+    }
+
+    // A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title`
+    // This will be removed later in favor of a `setContent` method
+    if (this.constructor.NAME === 'tooltip' && this.tip && this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML) {
+      this._disposePopper()
+      this.tip.remove()
+      this.tip = null
+    }
+
+    const tip = this.getTipElement()
+    const tipId = getUID(this.constructor.NAME)
+
+    tip.setAttribute('id', tipId)
+    this._element.setAttribute('aria-describedby', tipId)
+
+    if (this._config.animation) {
+      tip.classList.add(CLASS_NAME_FADE)
+    }
+
+    const placement = typeof this._config.placement === 'function' ?
+      this._config.placement.call(this, tip, this._element) :
+      this._config.placement
+
+    const attachment = this._getAttachment(placement)
+    this._addAttachmentClass(attachment)
+
+    const { container } = this._config
+    Data.set(tip, this.constructor.DATA_KEY, this)
+
+    if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
+      container.append(tip)
+      EventHandler.trigger(this._element, this.constructor.Event.INSERTED)
+    }
+
+    if (this._popper) {
+      this._popper.update()
+    } else {
+      this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))
+    }
+
+    tip.classList.add(CLASS_NAME_SHOW)
+
+    const customClass = this._resolvePossibleFunction(this._config.customClass)
+    if (customClass) {
+      tip.classList.add(...customClass.split(' '))
+    }
+
+    // If this is a touch-enabled device we add extra
+    // empty mouseover listeners to the body's immediate children;
+    // only needed because of broken event delegation on iOS
+    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+    if ('ontouchstart' in document.documentElement) {
+      [].concat(...document.body.children).forEach(element => {
+        EventHandler.on(element, 'mouseover', noop)
+      })
+    }
+
+    const complete = () => {
+      const prevHoverState = this._hoverState
+
+      this._hoverState = null
+      EventHandler.trigger(this._element, this.constructor.Event.SHOWN)
+
+      if (prevHoverState === HOVER_STATE_OUT) {
+        this._leave(null, this)
+      }
+    }
+
+    const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE)
+    this._queueCallback(complete, this.tip, isAnimated)
+  }
+
+  hide() {
+    if (!this._popper) {
+      return
+    }
+
+    const tip = this.getTipElement()
+    const complete = () => {
+      if (this._isWithActiveTrigger()) {
+        return
+      }
+
+      if (this._hoverState !== HOVER_STATE_SHOW) {
+        tip.remove()
+      }
+
+      this._cleanTipClass()
+      this._element.removeAttribute('aria-describedby')
+      EventHandler.trigger(this._element, this.constructor.Event.HIDDEN)
+
+      this._disposePopper()
+    }
+
+    const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE)
+    if (hideEvent.defaultPrevented) {
+      return
+    }
+
+    tip.classList.remove(CLASS_NAME_SHOW)
+
+    // If this is a touch-enabled device we remove the extra
+    // empty mouseover listeners we added for iOS support
+    if ('ontouchstart' in document.documentElement) {
+      [].concat(...document.body.children)
+        .forEach(element => EventHandler.off(element, 'mouseover', noop))
+    }
+
+    this._activeTrigger[TRIGGER_CLICK] = false
+    this._activeTrigger[TRIGGER_FOCUS] = false
+    this._activeTrigger[TRIGGER_HOVER] = false
+
+    const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE)
+    this._queueCallback(complete, this.tip, isAnimated)
+    this._hoverState = ''
+  }
+
+  update() {
+    if (this._popper !== null) {
+      this._popper.update()
+    }
+  }
+
+  // Protected
+
+  isWithContent() {
+    return Boolean(this.getTitle())
+  }
+
+  getTipElement() {
+    if (this.tip) {
+      return this.tip
+    }
+
+    const element = document.createElement('div')
+    element.innerHTML = this._config.template
+
+    const tip = element.children[0]
+    this.setContent(tip)
+    tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)
+
+    this.tip = tip
+    return this.tip
+  }
+
+  setContent(tip) {
+    this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER)
+  }
+
+  _sanitizeAndSetContent(template, content, selector) {
+    const templateElement = SelectorEngine.findOne(selector, template)
+
+    if (!content && templateElement) {
+      templateElement.remove()
+      return
+    }
+
+    // we use append for html objects to maintain js events
+    this.setElementContent(templateElement, content)
+  }
+
+  setElementContent(element, content) {
+    if (element === null) {
+      return
+    }
+
+    if (isElement(content)) {
+      content = getElement(content)
+
+      // content is a DOM node or a jQuery
+      if (this._config.html) {
+        if (content.parentNode !== element) {
+          element.innerHTML = ''
+          element.append(content)
+        }
+      } else {
+        element.textContent = content.textContent
+      }
+
+      return
+    }
+
+    if (this._config.html) {
+      if (this._config.sanitize) {
+        content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn)
+      }
+
+      element.innerHTML = content
+    } else {
+      element.textContent = content
+    }
+  }
+
+  getTitle() {
+    const title = this._element.getAttribute('data-bs-original-title') || this._config.title
+
+    return this._resolvePossibleFunction(title)
+  }
+
+  updateAttachment(attachment) {
+    if (attachment === 'right') {
+      return 'end'
+    }
+
+    if (attachment === 'left') {
+      return 'start'
+    }
+
+    return attachment
+  }
+
+  // Private
+
+  _initializeOnDelegatedTarget(event, context) {
+    return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())
+  }
+
+  _getOffset() {
+    const { offset } = this._config
+
+    if (typeof offset === 'string') {
+      return offset.split(',').map(val => Number.parseInt(val, 10))
+    }
+
+    if (typeof offset === 'function') {
+      return popperData => offset(popperData, this._element)
+    }
+
+    return offset
+  }
+
+  _resolvePossibleFunction(content) {
+    return typeof content === 'function' ? content.call(this._element) : content
+  }
+
+  _getPopperConfig(attachment) {
+    const defaultBsPopperConfig = {
+      placement: attachment,
+      modifiers: [
+        {
+          name: 'flip',
+          options: {
+            fallbackPlacements: this._config.fallbackPlacements
+          }
+        },
+        {
+          name: 'offset',
+          options: {
+            offset: this._getOffset()
+          }
+        },
+        {
+          name: 'preventOverflow',
+          options: {
+            boundary: this._config.boundary
+          }
+        },
+        {
+          name: 'arrow',
+          options: {
+            element: `.${this.constructor.NAME}-arrow`
+          }
+        },
+        {
+          name: 'onChange',
+          enabled: true,
+          phase: 'afterWrite',
+          fn: data => this._handlePopperPlacementChange(data)
+        }
+      ],
+      onFirstUpdate: data => {
+        if (data.options.placement !== data.placement) {
+          this._handlePopperPlacementChange(data)
+        }
+      }
+    }
+
+    return {
+      ...defaultBsPopperConfig,
+      ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
+    }
+  }
+
+  _addAttachmentClass(attachment) {
+    this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`)
+  }
+
+  _getAttachment(placement) {
+    return AttachmentMap[placement.toUpperCase()]
+  }
+
+  _setListeners() {
+    const triggers = this._config.trigger.split(' ')
+
+    triggers.forEach(trigger => {
+      if (trigger === 'click') {
+        EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event))
+      } else if (trigger !== TRIGGER_MANUAL) {
+        const eventIn = trigger === TRIGGER_HOVER ?
+          this.constructor.Event.MOUSEENTER :
+          this.constructor.Event.FOCUSIN
+        const eventOut = trigger === TRIGGER_HOVER ?
+          this.constructor.Event.MOUSELEAVE :
+          this.constructor.Event.FOCUSOUT
+
+        EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event))
+        EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event))
+      }
+    })
+
+    this._hideModalHandler = () => {
+      if (this._element) {
+        this.hide()
+      }
+    }
+
+    EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)
+
+    if (this._config.selector) {
+      this._config = {
+        ...this._config,
+        trigger: 'manual',
+        selector: ''
+      }
+    } else {
+      this._fixTitle()
+    }
+  }
+
+  _fixTitle() {
+    const title = this._element.getAttribute('title')
+    const originalTitleType = typeof this._element.getAttribute('data-bs-original-title')
+
+    if (title || originalTitleType !== 'string') {
+      this._element.setAttribute('data-bs-original-title', title || '')
+      if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {
+        this._element.setAttribute('aria-label', title)
+      }
+
+      this._element.setAttribute('title', '')
+    }
+  }
+
+  _enter(event, context) {
+    context = this._initializeOnDelegatedTarget(event, context)
+
+    if (event) {
+      context._activeTrigger[
+        event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER
+      ] = true
+    }
+
+    if (context.getTipElement().classList.contains(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
+      context._hoverState = HOVER_STATE_SHOW
+      return
+    }
+
+    clearTimeout(context._timeout)
+
+    context._hoverState = HOVER_STATE_SHOW
+
+    if (!context._config.delay || !context._config.delay.show) {
+      context.show()
+      return
+    }
+
+    context._timeout = setTimeout(() => {
+      if (context._hoverState === HOVER_STATE_SHOW) {
+        context.show()
+      }
+    }, context._config.delay.show)
+  }
+
+  _leave(event, context) {
+    context = this._initializeOnDelegatedTarget(event, context)
+
+    if (event) {
+      context._activeTrigger[
+        event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
+      ] = context._element.contains(event.relatedTarget)
+    }
+
+    if (context._isWithActiveTrigger()) {
+      return
+    }
+
+    clearTimeout(context._timeout)
+
+    context._hoverState = HOVER_STATE_OUT
+
+    if (!context._config.delay || !context._config.delay.hide) {
+      context.hide()
+      return
+    }
+
+    context._timeout = setTimeout(() => {
+      if (context._hoverState === HOVER_STATE_OUT) {
+        context.hide()
+      }
+    }, context._config.delay.hide)
+  }
+
+  _isWithActiveTrigger() {
+    for (const trigger in this._activeTrigger) {
+      if (this._activeTrigger[trigger]) {
+        return true
+      }
+    }
+
+    return false
+  }
+
+  _getConfig(config) {
+    const dataAttributes = Manipulator.getDataAttributes(this._element)
+
+    Object.keys(dataAttributes).forEach(dataAttr => {
+      if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
+        delete dataAttributes[dataAttr]
+      }
+    })
+
+    config = {
+      ...this.constructor.Default,
+      ...dataAttributes,
+      ...(typeof config === 'object' && config ? config : {})
+    }
+
+    config.container = config.container === false ? document.body : getElement(config.container)
+
+    if (typeof config.delay === 'number') {
+      config.delay = {
+        show: config.delay,
+        hide: config.delay
+      }
+    }
+
+    if (typeof config.title === 'number') {
+      config.title = config.title.toString()
+    }
+
+    if (typeof config.content === 'number') {
+      config.content = config.content.toString()
+    }
+
+    typeCheckConfig(NAME, config, this.constructor.DefaultType)
+
+    if (config.sanitize) {
+      config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn)
+    }
+
+    return config
+  }
+
+  _getDelegateConfig() {
+    const config = {}
+
+    for (const key in this._config) {
+      if (this.constructor.Default[key] !== this._config[key]) {
+        config[key] = this._config[key]
+      }
+    }
+
+    // In the future can be replaced with:
+    // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
+    // `Object.fromEntries(keysWithDifferentValues)`
+    return config
+  }
+
+  _cleanTipClass() {
+    const tip = this.getTipElement()
+    const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g')
+    const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex)
+    if (tabClass !== null && tabClass.length > 0) {
+      tabClass.map(token => token.trim())
+        .forEach(tClass => tip.classList.remove(tClass))
+    }
+  }
+
+  _getBasicClassPrefix() {
+    return CLASS_PREFIX
+  }
+
+  _handlePopperPlacementChange(popperData) {
+    const { state } = popperData
+
+    if (!state) {
+      return
+    }
+
+    this.tip = state.elements.popper
+    this._cleanTipClass()
+    this._addAttachmentClass(this._getAttachment(state.placement))
+  }
+
+  _disposePopper() {
+    if (this._popper) {
+      this._popper.destroy()
+      this._popper = null
+    }
+  }
+
+  // Static
+
+  static jQueryInterface(config) {
+    return this.each(function () {
+      const data = Tooltip.getOrCreateInstance(this, config)
+
+      if (typeof config === 'string') {
+        if (typeof data[config] === 'undefined') {
+          throw new TypeError(`No method named "${config}"`)
+        }
+
+        data[config]()
+      }
+    })
+  }
+}
+
+/**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ * add .Tooltip to jQuery only if jQuery is present
+ */
+
+defineJQueryPlugin(Tooltip)
+
+export default Tooltip
Index: trip-planner-front/node_modules/bootstrap/js/src/util/backdrop.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/backdrop.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/backdrop.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,130 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/backdrop.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import EventHandler from '../dom/event-handler'
+import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index'
+
+const Default = {
+  className: 'modal-backdrop',
+  isVisible: true, // if false, we use the backdrop helper without adding any element to the dom
+  isAnimated: false,
+  rootElement: 'body', // give the choice to place backdrop under different elements
+  clickCallback: null
+}
+
+const DefaultType = {
+  className: 'string',
+  isVisible: 'boolean',
+  isAnimated: 'boolean',
+  rootElement: '(element|string)',
+  clickCallback: '(function|null)'
+}
+const NAME = 'backdrop'
+const CLASS_NAME_FADE = 'fade'
+const CLASS_NAME_SHOW = 'show'
+
+const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`
+
+class Backdrop {
+  constructor(config) {
+    this._config = this._getConfig(config)
+    this._isAppended = false
+    this._element = null
+  }
+
+  show(callback) {
+    if (!this._config.isVisible) {
+      execute(callback)
+      return
+    }
+
+    this._append()
+
+    if (this._config.isAnimated) {
+      reflow(this._getElement())
+    }
+
+    this._getElement().classList.add(CLASS_NAME_SHOW)
+
+    this._emulateAnimation(() => {
+      execute(callback)
+    })
+  }
+
+  hide(callback) {
+    if (!this._config.isVisible) {
+      execute(callback)
+      return
+    }
+
+    this._getElement().classList.remove(CLASS_NAME_SHOW)
+
+    this._emulateAnimation(() => {
+      this.dispose()
+      execute(callback)
+    })
+  }
+
+  // Private
+
+  _getElement() {
+    if (!this._element) {
+      const backdrop = document.createElement('div')
+      backdrop.className = this._config.className
+      if (this._config.isAnimated) {
+        backdrop.classList.add(CLASS_NAME_FADE)
+      }
+
+      this._element = backdrop
+    }
+
+    return this._element
+  }
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...(typeof config === 'object' ? config : {})
+    }
+
+    // use getElement() with the default "body" to get a fresh Element on each instantiation
+    config.rootElement = getElement(config.rootElement)
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+
+  _append() {
+    if (this._isAppended) {
+      return
+    }
+
+    this._config.rootElement.append(this._getElement())
+
+    EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
+      execute(this._config.clickCallback)
+    })
+
+    this._isAppended = true
+  }
+
+  dispose() {
+    if (!this._isAppended) {
+      return
+    }
+
+    EventHandler.off(this._element, EVENT_MOUSEDOWN)
+
+    this._element.remove()
+    this._isAppended = false
+  }
+
+  _emulateAnimation(callback) {
+    executeAfterTransition(callback, this._getElement(), this._config.isAnimated)
+  }
+}
+
+export default Backdrop
Index: trip-planner-front/node_modules/bootstrap/js/src/util/component-functions.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/component-functions.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/component-functions.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,34 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/component-functions.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import EventHandler from '../dom/event-handler'
+import { getElementFromSelector, isDisabled } from './index'
+
+const enableDismissTrigger = (component, method = 'hide') => {
+  const clickEvent = `click.dismiss${component.EVENT_KEY}`
+  const name = component.NAME
+
+  EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
+    if (['A', 'AREA'].includes(this.tagName)) {
+      event.preventDefault()
+    }
+
+    if (isDisabled(this)) {
+      return
+    }
+
+    const target = getElementFromSelector(this) || this.closest(`.${name}`)
+    const instance = component.getOrCreateInstance(target)
+
+    // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
+    instance[method]()
+  })
+}
+
+export {
+  enableDismissTrigger
+}
Index: trip-planner-front/node_modules/bootstrap/js/src/util/focustrap.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/focustrap.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/focustrap.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,105 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/focustrap.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import EventHandler from '../dom/event-handler'
+import SelectorEngine from '../dom/selector-engine'
+import { typeCheckConfig } from './index'
+
+const Default = {
+  trapElement: null, // The element to trap focus inside of
+  autofocus: true
+}
+
+const DefaultType = {
+  trapElement: 'element',
+  autofocus: 'boolean'
+}
+
+const NAME = 'focustrap'
+const DATA_KEY = 'bs.focustrap'
+const EVENT_KEY = `.${DATA_KEY}`
+const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
+const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`
+
+const TAB_KEY = 'Tab'
+const TAB_NAV_FORWARD = 'forward'
+const TAB_NAV_BACKWARD = 'backward'
+
+class FocusTrap {
+  constructor(config) {
+    this._config = this._getConfig(config)
+    this._isActive = false
+    this._lastTabNavDirection = null
+  }
+
+  activate() {
+    const { trapElement, autofocus } = this._config
+
+    if (this._isActive) {
+      return
+    }
+
+    if (autofocus) {
+      trapElement.focus()
+    }
+
+    EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop
+    EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))
+    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))
+
+    this._isActive = true
+  }
+
+  deactivate() {
+    if (!this._isActive) {
+      return
+    }
+
+    this._isActive = false
+    EventHandler.off(document, EVENT_KEY)
+  }
+
+  // Private
+
+  _handleFocusin(event) {
+    const { target } = event
+    const { trapElement } = this._config
+
+    if (target === document || target === trapElement || trapElement.contains(target)) {
+      return
+    }
+
+    const elements = SelectorEngine.focusableChildren(trapElement)
+
+    if (elements.length === 0) {
+      trapElement.focus()
+    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
+      elements[elements.length - 1].focus()
+    } else {
+      elements[0].focus()
+    }
+  }
+
+  _handleKeydown(event) {
+    if (event.key !== TAB_KEY) {
+      return
+    }
+
+    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
+  }
+
+  _getConfig(config) {
+    config = {
+      ...Default,
+      ...(typeof config === 'object' ? config : {})
+    }
+    typeCheckConfig(NAME, config, DefaultType)
+    return config
+  }
+}
+
+export default FocusTrap
Index: trip-planner-front/node_modules/bootstrap/js/src/util/index.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/index.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/index.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,333 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/index.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const MAX_UID = 1000000
+const MILLISECONDS_MULTIPLIER = 1000
+const TRANSITION_END = 'transitionend'
+
+// Shoutout AngusCroll (https://goo.gl/pxwQGp)
+const toType = obj => {
+  if (obj === null || obj === undefined) {
+    return `${obj}`
+  }
+
+  return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
+}
+
+/**
+ * --------------------------------------------------------------------------
+ * Public Util Api
+ * --------------------------------------------------------------------------
+ */
+
+const getUID = prefix => {
+  do {
+    prefix += Math.floor(Math.random() * MAX_UID)
+  } while (document.getElementById(prefix))
+
+  return prefix
+}
+
+const getSelector = element => {
+  let selector = element.getAttribute('data-bs-target')
+
+  if (!selector || selector === '#') {
+    let hrefAttr = element.getAttribute('href')
+
+    // The only valid content that could double as a selector are IDs or classes,
+    // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
+    // `document.querySelector` will rightfully complain it is invalid.
+    // See https://github.com/twbs/bootstrap/issues/32273
+    if (!hrefAttr || (!hrefAttr.includes('#') && !hrefAttr.startsWith('.'))) {
+      return null
+    }
+
+    // Just in case some CMS puts out a full URL with the anchor appended
+    if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
+      hrefAttr = `#${hrefAttr.split('#')[1]}`
+    }
+
+    selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
+  }
+
+  return selector
+}
+
+const getSelectorFromElement = element => {
+  const selector = getSelector(element)
+
+  if (selector) {
+    return document.querySelector(selector) ? selector : null
+  }
+
+  return null
+}
+
+const getElementFromSelector = element => {
+  const selector = getSelector(element)
+
+  return selector ? document.querySelector(selector) : null
+}
+
+const getTransitionDurationFromElement = element => {
+  if (!element) {
+    return 0
+  }
+
+  // Get transition-duration of the element
+  let { transitionDuration, transitionDelay } = window.getComputedStyle(element)
+
+  const floatTransitionDuration = Number.parseFloat(transitionDuration)
+  const floatTransitionDelay = Number.parseFloat(transitionDelay)
+
+  // Return 0 if element or transition duration is not found
+  if (!floatTransitionDuration && !floatTransitionDelay) {
+    return 0
+  }
+
+  // If multiple durations are defined, take the first
+  transitionDuration = transitionDuration.split(',')[0]
+  transitionDelay = transitionDelay.split(',')[0]
+
+  return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER
+}
+
+const triggerTransitionEnd = element => {
+  element.dispatchEvent(new Event(TRANSITION_END))
+}
+
+const isElement = obj => {
+  if (!obj || typeof obj !== 'object') {
+    return false
+  }
+
+  if (typeof obj.jquery !== 'undefined') {
+    obj = obj[0]
+  }
+
+  return typeof obj.nodeType !== 'undefined'
+}
+
+const getElement = obj => {
+  if (isElement(obj)) { // it's a jQuery object or a node element
+    return obj.jquery ? obj[0] : obj
+  }
+
+  if (typeof obj === 'string' && obj.length > 0) {
+    return document.querySelector(obj)
+  }
+
+  return null
+}
+
+const typeCheckConfig = (componentName, config, configTypes) => {
+  Object.keys(configTypes).forEach(property => {
+    const expectedTypes = configTypes[property]
+    const value = config[property]
+    const valueType = value && isElement(value) ? 'element' : toType(value)
+
+    if (!new RegExp(expectedTypes).test(valueType)) {
+      throw new TypeError(
+        `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
+      )
+    }
+  })
+}
+
+const isVisible = element => {
+  if (!isElement(element) || element.getClientRects().length === 0) {
+    return false
+  }
+
+  return getComputedStyle(element).getPropertyValue('visibility') === 'visible'
+}
+
+const isDisabled = element => {
+  if (!element || element.nodeType !== Node.ELEMENT_NODE) {
+    return true
+  }
+
+  if (element.classList.contains('disabled')) {
+    return true
+  }
+
+  if (typeof element.disabled !== 'undefined') {
+    return element.disabled
+  }
+
+  return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'
+}
+
+const findShadowRoot = element => {
+  if (!document.documentElement.attachShadow) {
+    return null
+  }
+
+  // Can find the shadow root otherwise it'll return the document
+  if (typeof element.getRootNode === 'function') {
+    const root = element.getRootNode()
+    return root instanceof ShadowRoot ? root : null
+  }
+
+  if (element instanceof ShadowRoot) {
+    return element
+  }
+
+  // when we don't find a shadow root
+  if (!element.parentNode) {
+    return null
+  }
+
+  return findShadowRoot(element.parentNode)
+}
+
+const noop = () => {}
+
+/**
+ * Trick to restart an element's animation
+ *
+ * @param {HTMLElement} element
+ * @return void
+ *
+ * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
+ */
+const reflow = element => {
+  // eslint-disable-next-line no-unused-expressions
+  element.offsetHeight
+}
+
+const getjQuery = () => {
+  const { jQuery } = window
+
+  if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
+    return jQuery
+  }
+
+  return null
+}
+
+const DOMContentLoadedCallbacks = []
+
+const onDOMContentLoaded = callback => {
+  if (document.readyState === 'loading') {
+    // add listener on the first call when the document is in loading state
+    if (!DOMContentLoadedCallbacks.length) {
+      document.addEventListener('DOMContentLoaded', () => {
+        DOMContentLoadedCallbacks.forEach(callback => callback())
+      })
+    }
+
+    DOMContentLoadedCallbacks.push(callback)
+  } else {
+    callback()
+  }
+}
+
+const isRTL = () => document.documentElement.dir === 'rtl'
+
+const defineJQueryPlugin = plugin => {
+  onDOMContentLoaded(() => {
+    const $ = getjQuery()
+    /* istanbul ignore if */
+    if ($) {
+      const name = plugin.NAME
+      const JQUERY_NO_CONFLICT = $.fn[name]
+      $.fn[name] = plugin.jQueryInterface
+      $.fn[name].Constructor = plugin
+      $.fn[name].noConflict = () => {
+        $.fn[name] = JQUERY_NO_CONFLICT
+        return plugin.jQueryInterface
+      }
+    }
+  })
+}
+
+const execute = callback => {
+  if (typeof callback === 'function') {
+    callback()
+  }
+}
+
+const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
+  if (!waitForTransition) {
+    execute(callback)
+    return
+  }
+
+  const durationPadding = 5
+  const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding
+
+  let called = false
+
+  const handler = ({ target }) => {
+    if (target !== transitionElement) {
+      return
+    }
+
+    called = true
+    transitionElement.removeEventListener(TRANSITION_END, handler)
+    execute(callback)
+  }
+
+  transitionElement.addEventListener(TRANSITION_END, handler)
+  setTimeout(() => {
+    if (!called) {
+      triggerTransitionEnd(transitionElement)
+    }
+  }, emulatedDuration)
+}
+
+/**
+ * Return the previous/next element of a list.
+ *
+ * @param {array} list    The list of elements
+ * @param activeElement   The active element
+ * @param shouldGetNext   Choose to get next or previous element
+ * @param isCycleAllowed
+ * @return {Element|elem} The proper element
+ */
+const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
+  let index = list.indexOf(activeElement)
+
+  // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
+  if (index === -1) {
+    return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0]
+  }
+
+  const listLength = list.length
+
+  index += shouldGetNext ? 1 : -1
+
+  if (isCycleAllowed) {
+    index = (index + listLength) % listLength
+  }
+
+  return list[Math.max(0, Math.min(index, listLength - 1))]
+}
+
+export {
+  getElement,
+  getUID,
+  getSelectorFromElement,
+  getElementFromSelector,
+  getTransitionDurationFromElement,
+  triggerTransitionEnd,
+  isElement,
+  typeCheckConfig,
+  isVisible,
+  isDisabled,
+  findShadowRoot,
+  noop,
+  getNextActiveElement,
+  reflow,
+  getjQuery,
+  onDOMContentLoaded,
+  isRTL,
+  defineJQueryPlugin,
+  execute,
+  executeAfterTransition
+}
Index: trip-planner-front/node_modules/bootstrap/js/src/util/sanitizer.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/sanitizer.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/sanitizer.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,126 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/sanitizer.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const uriAttributes = new Set([
+  'background',
+  'cite',
+  'href',
+  'itemtype',
+  'longdesc',
+  'poster',
+  'src',
+  'xlink:href'
+])
+
+const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
+
+/**
+ * A pattern that recognizes a commonly useful subset of URLs that are safe.
+ *
+ * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
+ */
+const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i
+
+/**
+ * A pattern that matches safe data URLs. Only matches image, video and audio types.
+ *
+ * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
+ */
+const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i
+
+const allowedAttribute = (attribute, allowedAttributeList) => {
+  const attributeName = attribute.nodeName.toLowerCase()
+
+  if (allowedAttributeList.includes(attributeName)) {
+    if (uriAttributes.has(attributeName)) {
+      return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue))
+    }
+
+    return true
+  }
+
+  const regExp = allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)
+
+  // Check if a regular expression validates the attribute.
+  for (let i = 0, len = regExp.length; i < len; i++) {
+    if (regExp[i].test(attributeName)) {
+      return true
+    }
+  }
+
+  return false
+}
+
+export const DefaultAllowlist = {
+  // Global attributes allowed on any supplied element below.
+  '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
+  a: ['target', 'href', 'title', 'rel'],
+  area: [],
+  b: [],
+  br: [],
+  col: [],
+  code: [],
+  div: [],
+  em: [],
+  hr: [],
+  h1: [],
+  h2: [],
+  h3: [],
+  h4: [],
+  h5: [],
+  h6: [],
+  i: [],
+  img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
+  li: [],
+  ol: [],
+  p: [],
+  pre: [],
+  s: [],
+  small: [],
+  span: [],
+  sub: [],
+  sup: [],
+  strong: [],
+  u: [],
+  ul: []
+}
+
+export function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
+  if (!unsafeHtml.length) {
+    return unsafeHtml
+  }
+
+  if (sanitizeFn && typeof sanitizeFn === 'function') {
+    return sanitizeFn(unsafeHtml)
+  }
+
+  const domParser = new window.DOMParser()
+  const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')
+  const elements = [].concat(...createdDocument.body.querySelectorAll('*'))
+
+  for (let i = 0, len = elements.length; i < len; i++) {
+    const element = elements[i]
+    const elementName = element.nodeName.toLowerCase()
+
+    if (!Object.keys(allowList).includes(elementName)) {
+      element.remove()
+
+      continue
+    }
+
+    const attributeList = [].concat(...element.attributes)
+    const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])
+
+    attributeList.forEach(attribute => {
+      if (!allowedAttribute(attribute, allowedAttributes)) {
+        element.removeAttribute(attribute.nodeName)
+      }
+    })
+  }
+
+  return createdDocument.body.innerHTML
+}
Index: trip-planner-front/node_modules/bootstrap/js/src/util/scrollbar.js
===================================================================
--- trip-planner-front/node_modules/bootstrap/js/src/util/scrollbar.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
+++ trip-planner-front/node_modules/bootstrap/js/src/util/scrollbar.js	(revision 6a3a178323fd905112b5392bd9d3cb83b66ef2d3)
@@ -0,0 +1,97 @@
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v5.1.3): util/scrollBar.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+import SelectorEngine from '../dom/selector-engine'
+import Manipulator from '../dom/manipulator'
+import { isElement } from './index'
+
+const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
+const SELECTOR_STICKY_CONTENT = '.sticky-top'
+
+class ScrollBarHelper {
+  constructor() {
+    this._element = document.body
+  }
+
+  getWidth() {
+    // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
+    const documentWidth = document.documentElement.clientWidth
+    return Math.abs(window.innerWidth - documentWidth)
+  }
+
+  hide() {
+    const width = this.getWidth()
+    this._disableOverFlow()
+    // give padding to element to balance the hidden scrollbar width
+    this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width)
+    // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
+    this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width)
+    this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width)
+  }
+
+  _disableOverFlow() {
+    this._saveInitialAttribute(this._element, 'overflow')
+    this._element.style.overflow = 'hidden'
+  }
+
+  _setElementAttributes(selector, styleProp, callback) {
+    const scrollbarWidth = this.getWidth()
+    const manipulationCallBack = element => {
+      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
+        return
+      }
+
+      this._saveInitialAttribute(element, styleProp)
+      const calculatedValue = window.getComputedStyle(element)[styleProp]
+      element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`
+    }
+
+    this._applyManipulationCallback(selector, manipulationCallBack)
+  }
+
+  reset() {
+    this._resetElementAttributes(this._element, 'overflow')
+    this._resetElementAttributes(this._element, 'paddingRight')
+    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight')
+    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight')
+  }
+
+  _saveInitialAttribute(element, styleProp) {
+    const actualValue = element.style[styleProp]
+    if (actualValue) {
+      Manipulator.setDataAttribute(element, styleProp, actualValue)
+    }
+  }
+
+  _resetElementAttributes(selector, styleProp) {
+    const manipulationCallBack = element => {
+      const value = Manipulator.getDataAttribute(element, styleProp)
+      if (typeof value === 'undefined') {
+        element.style.removeProperty(styleProp)
+      } else {
+        Manipulator.removeDataAttribute(element, styleProp)
+        element.style[styleProp] = value
+      }
+    }
+
+    this._applyManipulationCallback(selector, manipulationCallBack)
+  }
+
+  _applyManipulationCallback(selector, callBack) {
+    if (isElement(selector)) {
+      callBack(selector)
+    } else {
+      SelectorEngine.find(selector, this._element).forEach(callBack)
+    }
+  }
+
+  isOverflowing() {
+    return this.getWidth() > 0
+  }
+}
+
+export default ScrollBarHelper
