diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 43c65f365..40e219551 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ # Select image from https://hub.docker.com/_/php/ #image: php:7.2 -# Use a prepared Hubzilla image to optimise pipeline run +# Use a prepared Hubzilla image to optimise pipeline duration image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.2 @@ -32,55 +32,28 @@ variables: before_script: +# pecl and composer do not work with PHP production restrictions (from Hubzilla Docker image) +- if [ -f /usr/local/etc/php/conf.d/z_prod.ini ]; then mv /usr/local/etc/php/conf.d/z_prod.ini /usr/local/etc/php/conf.d/z_prod.ini.off; fi # Install & enable Xdebug for code coverage reports - pecl install xdebug - docker-php-ext-enable xdebug # Install composer - curl -sS https://getcomposer.org/installer | php # Install dev libraries from composer -- php composer.phar install --no-progress +- php ./composer.phar install --no-progress -# test PHP7 with MySQL 5.7 -php7.2_mysql 1/2: +# hidden job definition with template for MySQL/MariaDB +.job_template_mysql: &job_definition_mysql stage: test - services: - - mysql:5.7 script: - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text - -# test PHP7 with MySQL latest (8) -php7.2_mysql 2/2: - stage: test - services: - - name: mysql:latest - command: ["--default-authentication-plugin=mysql_native_password"] - script: - - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text - - -# test PHP7 with MariaDB latest (10.3) -php7.2_mariadb: - stage: test - services: - - name: mariadb:latest - alias: mysql - script: - - echo "USE $MYSQL_DATABASE; $(cat ./install/schema_mysql.sql)" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - echo "SHOW DATABASES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - echo "USE $MYSQL_DATABASE; SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" - - vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text - - -# test PHP7 with PostgreSQL latest -php7.2_postgres: +# hidden job definition with template for PostgreSQL +.job_template_postgres: &job_definition_postgres stage: test services: - postgres:latest @@ -95,7 +68,10 @@ php7.2_postgres: #- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "\dt;" # Run the actual tests - vendor/bin/phpunit --configuration tests/phpunit-pgsql.xml --testdox - artifacts: + +# hidden job definition with artifacts config template +.artifacts_template: + artifacts: &artifacts_template expire_in: 1 week # Gitlab should show the results, but has problems parsing PHPUnit's junit file. reports: @@ -106,7 +82,52 @@ php7.2_postgres: - tests/results/ -# Generate Doxygen API Documentation and deploy it at GitLab pages +# PHP7.2 with MySQL 5.7 +php7.2_mysql5.7: + <<: *job_definition_mysql + services: + - mysql:5.7 + + +# PHP7.2 with MySQL 8 (latest) +php7.2_mysql8: + <<: *job_definition_mysql + services: + - name: mysql:8 + command: ["--default-authentication-plugin=mysql_native_password"] + + +# PHP7.2 with MariaDB 10.2 +php7.2_mariadb10.2: + <<: *job_definition_mysql + services: + - name: mariadb:10.2 + alias: mysql + + +# PHP7.3 with MariaDB 10.3 (latest) +php7.3_mariadb10.3: + <<: *job_definition_mysql + image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3 + services: + - name: mariadb:10.3 + alias: mysql + + +# PHP7.2 with PostgreSQL latest (11) +php7.2_postgres11: + <<: *job_definition_postgres + artifacts: *artifacts_template + + +# PHP7.3 with PostgreSQL latest (11) +php7.3_postgres11: + <<: *job_definition_postgres + image: registry.gitlab.com/dawnbreak/hubzilla/core:php7.3 + artifacts: *artifacts_template + + +# Generate Doxygen API Documentation and deploy it as GitLab pages pages: stage: deploy cache: {} diff --git a/.homeinstall/README.md b/.homeinstall/README.md index d63931a84..45e1ba0e6 100644 --- a/.homeinstall/README.md +++ b/.homeinstall/README.md @@ -1,16 +1,43 @@ # Hubzilla at Home next to your Router -Run hubzilla-setup.sh for an unattended installation of hubzilla. +This readme will show you how to install and run Hubzilla or Zap at home. + +The installation is done by a script. + +What the script will do for you... + ++ install everything required by Zap/Hubzilla, basically a web server (Apache), PHP, a database (MySQL), certbot,... ++ create a database ++ run certbot to have everything for a secure connection (httpS) ++ create a script for daily maintenance + - backup to external disk (certificates, database, /var/www/) + - renew certfificate (letsencrypt) + - update of Zap/Hubzilla + - update of Debian + - restart ++ create cron jobs for + - DynDNS (selfHOST.de or freedns.afraid.org) every 5 minutes + - Master.php for Zap/Hubzilla every 10 minutes + - daily maintenance script every day at 05:30 The script is known to work without adjustments with + Hardware - - Mini-PC with Debian-9.5-amd64, or - - Rapberry 3 with Raspbian, Debian-9.5 + - Mini-PC with Debian 9 (stretch), or + - Rapberry 3 with Raspbian, Debian 9 + DynDNS - selfHOST.de - freedns.afraid.org +The script can install both [Hubzilla](https://zotlabs.org/page/hubzilla/hubzilla-project) and [Zap](https://zotlabs.com/zap/). Make sure to use the correct GIT repositories. + ++ Hubzilla + - core: git clone https://framagit.org/hubzilla/core.git html (in this readme) + - addons: util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons (in hubzilla-setup.sh) ++ Zap + - core: git clone https://framagit.org/zot/zap.git html (in this readme) + - addons: util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons (in hubzilla-setup.sh) + ## Disclaimers - This script does work with Debian 9 only. @@ -29,7 +56,7 @@ Hardware Software + Fresh installation of Debian 9 (Stretch) -+ Router with open ports 80 and 443 for your Hub ++ Router with open ports 80 and 443 for your web server ## The basic steps (quick overview) @@ -44,10 +71,9 @@ Software - nano hubzilla-config.txt - Read the comments carefully - Enter your values: db pass, domain, values for dyn DNS - - Make sure your external drive (for backups) is mounted + - Prepare your external disk for backups - hubzilla-setup.sh as root - ... wait, wait, wait until the script is finised - - reboot + Open your domain with a browser and step throught the initial configuration of hubzilla. ## Troubleshooting @@ -66,58 +92,28 @@ In Admin settings of hubzilla or via terminal # Step-by-Step in Detail -## Preparations Hardware - -### Mini-PC - -### Recommended: USB Drive for Backups - -The installation will create a daily backup written to an external drive. - -The USB drive must be compatible with the filesystems - -- ext4 (if you do not want to encrypt the USB) -- LUKS + ext4 (if you want to encrypt the USB) - -The backup includes - -- Hubzilla DB -- Hubzilla installation /var/www/html -- Certificates for letsencrypt - ## Preparations Software -### Install Debian Linux on the Mini-PC +## Install Debian 9 -Download the stable Debian at https://www.debian.org/ -(Debian 8 is no longer supported.) +Provided you use a Raspberry Pi 3... -Create bootable USB drive with Debian on it.You could use +Download the OS Raspbian from https://www.raspberrypi.org/downloads/raspbian/ -- unetbootin, https://en.wikipedia.org/wiki/UNetbootin -- or simply the linux command "dd" +Follow the installation instruction there. -Example for command dd... +## Configure your Router - su - - dd if=2018-10-09-raspbian-stretch.img of=/dev/mmcblk0 +Your web has to be visible in the internet. -Do not forget to unmount the SD card before and check if unmounted like in this example... - - su - - umount /dev/mmcblk0* - df -h - - -Switch off your mini pc, plug in your USB drive and start the mini pc from the -stick. Install Debian. Follow the instructions of the installation. - -### Configure your Router - -Open the ports 80 and 443 on your router for your Debian +Open the ports 80 and 443 on your router for your Debian. Make sure your web server is marked as "exposed host". ## Preparations Dynamic IP Address +Follow the instructions in .homeinstall/hubzilla-config.txt. + +In short... + Your Hubzilla must be reachable by a domain that you can type in your browser cooldomain.org @@ -132,105 +128,15 @@ There are two ways to get a domain... ...for example buy at selfHOST.de -The cost are around 10,- € once and 1,50 € per month (2017). +The cost is 1,50 € per month (2019). ### Method 2: Register a free subdomain ...for example register at freedns.afraid.org -Follow the instructions in .homeinstall/hubzilla-config.txt. +## Note on Rasperry - -## Install Hubzilla on your Debian - -Login to your debian -(Provided your username is "you" and the name of the mini pc is "debian". You -could take the IP address instead of "debian") - - ssh -X you@debian - -Change to root user - - su -l - -Install git - - apt-get install git - -Make the directory for apache and change diretory to it - - mkdir /var/www - cd /var/www/ - -Clone hubzilla from git ("git pull" will update it later) - - git clone https://framagit.org/hubzilla/core.git html - -Change to the install script - - cd html/.homeinstall/ - -Copy the template file - - cp hubzilla-config.txt.template hubzilla-config.txt - -Modify the file "hubzilla-config.txt". Read the instructions there carefully and enter your values. - - nano hubzilla-config.txt - -Make sure your external drive (for backups) is plugged in and can be mounted as configured in "hubzilla-config.txt". Otherwise the daily backups will not work. - -Run the script - - ./hubzilla-setup.sh - -Wait... The script should not finish with an error message. - -In a webbrowser open your domain. -Expected: A test page of hubzilla is shown. All checks there should be -successfull. Go on... -Expected: A page for the Hubzilla server configuration shows up. - -Leave db server name "127.0.0.1" and port "0" untouched. - -Enter - -- DB user name = hubzilla -- DB pass word = This is the password you entered in "hubzilla-config.txt" -- DB name = hubzilla - -Leave db type "MySQL" untouched. - -Follow the instructions in the next pages. - -Recommended: Set path to imagemagick - -- in admin settings of hubzilla or -- via terminal - - util/config system.imagick_convert_path /usr/bin/convert - -After the daily script was executed at 05:30 (am) - -- look at /var/www/html/hubzilla-daily.log -- check your backup on the external drive -- optionally view the daily log under yourdomain.org/admin/logs/ - - set the logfile to var/www/html/hubzilla-daily.log - - -## Install Hubzilla in a Virtual Machine for Test Purposes - -Modify the file "hubzilla-config.txt". - - nano hubzilla-config.txt - -There use - - le_domain=localhost - -## Note for the Rasperry - -The script was tested with an Raspberry 3 under Raspian (Debian 9.5, 2018-10-09-raspbian-stretch.img). +The script was tested with an Raspberry 3 under Raspian, Debian 9. It is recommended to run the Raspi without graphical frontend (X-Server). Use... @@ -240,7 +146,7 @@ to boot the Rapsi to the client console. DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI! -If the validation of the mail address fails for the very first registered user... +On a Raspian Stretch (Debian 9) the validation of the mail address fails for the very first user. This used to happen on some *bsd distros but there was some work to fix that a year ago (2017). So if your system isn't registered in DNS or DNS isn't active do diff --git a/.homeinstall/hubzilla-config.txt.template b/.homeinstall/hubzilla-config.txt.template index e42da0e4e..f0bf6121c 100644 --- a/.homeinstall/hubzilla-config.txt.template +++ b/.homeinstall/hubzilla-config.txt.template @@ -2,8 +2,8 @@ ### MANDATORY - database password ############# # # Please give your database password +# It is better to not use blanks inside the password. # Example: db_pass=pass_word_with_no_blanks_in_it -# Example: db_pass="this password has blanks in it" db_pass= ############################################### @@ -18,9 +18,12 @@ db_pass= # Example: my.cooldomain.org # Example: cooldomain.org # -# Example: localhost (test installation without certificates for httpS) +# You might use "localhost" for a LOCAL TEST installation. +# This is usefull if you want to debug the server inside a VM. # -# Email is optional +# Example: localhost +# +# Email is optional if you use "localhost". # # le_domain= @@ -30,7 +33,7 @@ le_email= ### OPTIONAL - selfHOST - dynamic IP address ## # # 1. Register a domain at selfhost.de -# - choose offer "DOMAIN dynamisch" 1,50€/mon at 08.01.2016 +# - choose offer "DOMAIN dynamisch" 1,50€/mon at 04/2019 # 2. Get your configuration for dynamic IP update # - Log in at selfhost.de # - go to "DynDNS Accounte" diff --git a/.homeinstall/hubzilla-setup.sh b/.homeinstall/hubzilla-setup.sh old mode 100755 new mode 100644 index 1f3ad5db5..023ef7afc --- a/.homeinstall/hubzilla-setup.sh +++ b/.homeinstall/hubzilla-setup.sh @@ -3,7 +3,10 @@ # How to use # ---------- # -# This file automates the installation of hubzilla under Debian Linux +# This file automates the installation of +# - hubzilla: https://zotlabs.org/page/hubzilla/hubzilla-project and +# - zap: https://zotlabs.com/zap/ +# under Debian Linux # # 1) Copy the file "hubzilla-config.txt.template" to "hubzilla-config.txt" # Follow the instuctions there @@ -25,16 +28,14 @@ # * php, # * mysql - the database for hubzilla, # * phpmyadmin, -# * git to download and update hubzilla itself +# * git to download and update hubzilla addon # - download hubzilla core and addons # - configure cron -# * "poller.php" for regular background prozesses of hubzilla -# * to_do "apt-get update" and "apt-get dist-upgrade" to keep linux -# up-to-date -# * to_do backup hubzillas database and files (rsnapshot) -# - configure dynamic ip with cron -# - to_do letsencrypt -# - to_do redirection to https +# * "Master.php" for regular background prozesses of hubzilla +# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date +# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org +# * backup hubzillas database and files (rsync) +# - letsencrypt # # # Discussion @@ -43,26 +44,11 @@ # Security - password is the same for mysql-server, phpmyadmin and hubzilla db # - The script runs into installation errors for phpmyadmin if it uses # different passwords. For the sake of simplicity one singel password. -# -# Security - suhosin for PHP -# - The script does not install suhosin. -# - Is the security package suhosin usefull or not usefull? # # Hubzilla - email verification # - The script switches off email verification off in all htconfig.tpl. # Example: /var/www/html/view/en/htconfig.tpl # - Is this a silly idea or not? -# -# -# Remove Hubzilla (for a fresh start using the script) -# ---------------------------------------------------- -# -# You could use /var/www/hubzilla-remove.sh -# that is created by hubzilla-setup.sh. -# -# The script will remove (almost everything) what was installed by the script. -# After the removal you could run the script again to have a fresh install -# of all applications including hubzilla and its database. # # How to restore from backup # -------------------------- @@ -76,18 +62,10 @@ # # hubzilla-daily.sh makes a (daily) backup of all relevant files # - /var/lib/mysql/ > hubzilla database -# - /var/www/html/ > hubzilla from github -# - /var/www/letsencrypt/ > certificates +# - /var/www/ > hubzilla/zap from github +# - /etc/letsencrypt/ > certificates # -# hubzilla-daily.sh writes the backup -# - either to an external disk compatible to LUKS+ext4 (see hubzilla-config.txt) -# - or to /var/cache/rsnapshot in case the external disk is not plugged in -# -# Restore backup -# - - - - - - - -# -# This was not tested yet. -# Bacically you can copy the files from the backup to the server. +# hubzilla-daily.sh writes the backup to an external disk compatible to LUKS+ext4 (see hubzilla-config.txt) # # Credits # ------- @@ -136,11 +114,11 @@ function check_config { # backup is important and should be checked if [ -n "$backup_device_name" ] then - if [ ! -d "$backup_mount_point" ] - then - mkdir "$backup_mount_point" - fi - device_mounted=0 + if [ ! -d "$backup_mount_point" ] + then + mkdir "$backup_mount_point" + fi + device_mounted=0 if fdisk -l | grep -i "$backup_device_name.*linux" then print_info "ok - filesystem of external device is linux" @@ -264,7 +242,7 @@ function install_sendmail { function install_php { # openssl and mbstring are included in libapache2-mod-php print_info "installing php..." - nocheck_install "libapache2-mod-php php php-pear php-curl php-mcrypt php-gd" + nocheck_install "libapache2-mod-php php php-pear php-curl php-mcrypt php-gd php-mysqli php-mbstring php-xml" sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.0/apache2/php.ini sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.0/apache2/php.ini } @@ -449,11 +427,11 @@ function configure_cron_selfhost { print_info "configure cron for selfhost..." if [ -z "$selfhost_user" ] then - print_info "freedns is not configured because freedns_key is empty in $configfile" + print_info "selfhost is not configured because selfhost_key is empty in $configfile" else # Use cron for dynamich ip update # - at reboot - # - every 30 minutes + # - every 5 minutes if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ] then echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab @@ -471,89 +449,24 @@ function install_letsencrypt { then die "Failed to install let's encrypt: 'le_domain' is empty in $configfile" fi - # configure apache - apache_le_conf=/etc/apache2/sites-available/le-default.conf - if [ -f $apache_le_conf ] + # check if user gave mail address + if [ -z "$le_email" ] then - print_info "$apache_le_conf exist already" + die "Failed to install let's encrypt: 'le_domain' is empty in $configfile" + fi + nocheck_install "apt-transport-https" + # add backports to your sources.list + backports_list=/etc/apt/sources.list.d/backports.list + if [ -f $backports_list ] + then + print_info "$backports_list exist already" else - cat > $apache_le_conf < - Options FollowSymLinks - Allow from all - -END - a2ensite le-default.conf - service apache2 restart + echo "deb https://deb.debian.org/debian stretch-backports main" > $backports_list fi - # download the shell script - if [ -d $le_dir ] - then - print_info "letsenrypt exists already (nothing downloaded > no certificate created and registered)" - return 0 - fi - git clone https://github.com/lukas2511/dehydrated $le_dir - cd $le_dir - # create config file for letsencrypt.sh - echo "WELLKNOWN=$le_dir" > $le_dir/config.sh - if [ -n "$le_email" ] - then - echo "CONTACT_EMAIL=$le_email" >> $le_dir/config.sh - fi - # create domain file for letsencrypt.sh - # WATCH THIS: - # - It did not work wit "sub.domain.org www.sub.domain.org". - # - So just use "sub.domain.org" only! - echo "$le_domain" > $le_dir/domains.txt - # test apache config for letsencrpyt - url_http=http://$le_domain/.well-known/acme-challenge/domains.txt - wget_output=$(wget -nv --spider --max-redirect 0 $url_http) - if [ $? -ne 0 ] - then - die "Failed to load $url_http" - fi - # accept terms of service of letsencrypt - ./dehydrated --register --accept-terms - # run script dehydrated - # - ./dehydrated --cron --config $le_dir/config.sh -} - -function configure_apache_for_https { - print_info "configuring apache to use httpS ..." - # letsencrypt.sh - # - # "${BASEDIR}/certs/${domain}/privkey.pem" - # "${BASEDIR}/certs/${domain}/cert.pem" - # "${BASEDIR}/certs/${domain}/fullchain.pem" - # - SSLCertificateFile=${le_dir}/certs/${le_domain}/cert.pem - SSLCertificateKeyFile=${le_dir}/certs/${le_domain}/privkey.pem - SSLCertificateChainFile=${le_dir}/certs/${le_domain}/fullchain.pem - if [ ! -f $SSLCertificateFile ] - then - print_warn "Failed to configure apache for httpS: Missing certificate file $SSLCertificateFile" - return 0 - fi - # make sure that the ssl mode is enabled - print_info "...configuring apache to use httpS - a2enmod ssl ..." - a2enmod ssl - # modify apach' ssl conf file - if grep -i "ServerName" $sslconf - then - print_info "seems that apache was already configered to use httpS with $sslconf" - else - sed -i "s/ServerAdmin.*$/ServerAdmin webmaster@localhost\\n ServerName ${le_domain}/" $sslconf - fi - sed -i s#/etc/ssl/certs/ssl-cert-snakeoil.pem#$SSLCertificateFile# $sslconf - sed -i s#/etc/ssl/private/ssl-cert-snakeoil.key#$SSLCertificateKeyFile# $sslconf - sed -i s#/etc/apache2/ssl.crt/server-ca.crt#$SSLCertificateChainFile# $sslconf - sed -i s/#SSLCertificateChainFile/SSLCertificateChainFile/ $sslconf - # apply changes - a2ensite default-ssl.conf + apt-get -y update + DEBIAN_FRONTEND=noninteractive apt-get -q -y -t stretch-backports install certbot python-certbot-apache + print_info "run certbot ..." + certbot --apache -w /var/www/html -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir service apache2 restart } @@ -572,7 +485,10 @@ function check_https { function install_hubzilla { print_info "installing hubzilla addons..." cd /var/www/html/ - util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons + # if you install Hubzilla + util/add_addon_repo https://framagit.org/hubzilla/addons hzaddons + # if you install ZAP + #util/add_addon_repo https://framagit.org/zot/zap-addons.git zaddons mkdir -p "store/[data]/smarty3" chmod -R 777 store touch .htconfig.php @@ -582,7 +498,7 @@ function install_hubzilla { chown root:www-data /var/www/html/ chown root:www-data /var/www/html/.htaccess chmod 0644 /var/www/html/.htaccess - # try to switch off email registration + print_info "try to switch off email registration..." sed -i "s/verify_email.*1/verify_email'] = 0/" /var/www/html/view/*/ht* if [ -n "`grep -r 'verify_email.*1' /var/www/html/view/`" ] then @@ -591,49 +507,9 @@ function install_hubzilla { print_info "installed hubzilla" } -function rewrite_to_https { - print_info "configuring apache to redirect http to httpS ..." - htaccessfile=/var/www/html/.htaccess - if grep -i "https" $htaccessfile - then - print_info "...configuring apache to redirect http to httpS was already done in $htaccessfile" - else - sed -i "s#QSA]#QSA]\\n RewriteCond %{SERVER_PORT} !^443$\\n RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]#" $htaccessfile - fi - service apache2 restart -} - -# This will allways overwrite both config files -# - internal disk -# - external disk (LUKS + ext4) -# of rsnapshot for hubzilla -function install_rsnapshot { - print_info "installing rsnapshot..." - nocheck_install "rsnapshot" - # internal disk - cp -f /etc/rsnapshot.conf $snapshotconfig - sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig - sed -i "s/^backup/#backup/" $snapshotconfig - echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig - echo "backup /var/www/html/ localhost/" >> $snapshotconfig - echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig - # external disk - if [ -n "$backup_device_name" ] - then - cp -f /etc/rsnapshot.conf $snapshotconfig_external_device - sed -i "s#snapshot_root.*#snapshot_root $backup_mount_point#" $snapshotconfig_external_device - sed -i "/alpha/s/6/30/" $snapshotconfig_external_device - sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig_external_device - sed -i "s/^backup/#backup/" $snapshotconfig_external_device - if [ -z "`grep 'letsencrypt' $snapshotconfig_external_device`" ] - then - echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig_external_device - echo "backup /var/www/html/ localhost/" >> $snapshotconfig_external_device - echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig_external_device - fi - else - print_info "No backup configuration (rsnapshot) for external device configured. Reason: backup_device_name and/or backup_device_pass not given in $configfile" - fi +function install_rsync { + print_info "installing rsync..." + nocheck_install "rsync" } function install_cryptosetup { @@ -644,28 +520,28 @@ function install_cryptosetup { function configure_cron_daily { print_info "configuring cron..." # every 10 min for poller.php - if [ -z "`grep 'poller.php' /etc/crontab`" ] + if [ -z "`grep 'Master.php' /etc/crontab`" ] then echo "*/10 * * * * www-data cd /var/www/html; php Zotlabs/Daemon/Master.php Cron >> /dev/null 2>&1" >> /etc/crontab fi # Run external script daily at 05:30 # - stop apache and mysql-server - # - backup hubzilla + # - renew the certificate of letsencrypt + # - backup db, files (/var/www/html), certificates if letsencrypt # - update hubzilla core and addon # - update and upgrade linux - # - reboot + # - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system echo "#!/bin/sh" > /var/www/$hubzilladaily echo "#" >> /var/www/$hubzilladaily echo "echo \" \"" >> /var/www/$hubzilladaily echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily echo "echo \" \"" >> /var/www/$hubzilladaily echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$hubzilladaily -echo "bash $le_dir/dehydrated --cron --config $le_dir/config.sh" >> /var/www/$hubzilladaily +echo "certbot renew --noninteractive" >> /var/www/$hubzilladaily echo "#" >> /var/www/$hubzilladaily -echo "# stop hubzilla" >> /var/www/$hubzilladaily -echo "echo \"\$(date) - stoping apache and mysql...\"" >> /var/www/$hubzilladaily +echo "echo \"\$(date) - stopping apache and mysql...\"" >> /var/www/$hubzilladaily echo "service apache2 stop" >> /var/www/$hubzilladaily -echo "/etc/init.d/mysql stop # to avoid inconsistancies" >> /var/www/$hubzilladaily +echo "/etc/init.d/mysql stop # to avoid inconsistencies" >> /var/www/$hubzilladaily echo "#" >> /var/www/$hubzilladaily echo "# backup" >> /var/www/$hubzilladaily echo "echo \"\$(date) - try to mount external device for backup...\"" >> /var/www/$hubzilladaily @@ -696,11 +572,13 @@ echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hub echo " then" >> /var/www/$hubzilladaily echo " device_mounted=1" >> /var/www/$hubzilladaily echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily -echo " rsnapshot -c $snapshotconfig_external_device alpha" >> /var/www/$hubzilladaily -echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily -echo " df -h" >> /var/www/$hubzilladaily -echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily -echo " du -h $backup_mount_point | grep mysql/hubzilla" >> /var/www/$hubzilladaily +echo " rsync -a --delete /var/lib/mysql/ /media/hubzilla_backup/mysql" >> /var/www/$hubzilladaily +echo " rsync -a --delete /var/www/ /media/hubzilla_backup/www" >> /var/www/$hubzilladaily +echo " rsync -a --delete /etc/letsencrypt/ /media/hubzilla_backup/letsencrypt" >> /var/www/$hubzilladaily +echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily +echo " df -h" >> /var/www/$hubzilladaily +echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily +echo " du -h $backup_mount_point | grep mysql/hubzilla" >> /var/www/$hubzilladaily echo " echo \"unmounting backup device...\"" >> /var/www/$hubzilladaily echo " umount $backup_mount_point" >> /var/www/$hubzilladaily echo " else" >> /var/www/$hubzilladaily @@ -722,18 +600,16 @@ echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily echo "du -h /var/lib/mysql/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily echo "#" >> /var/www/$hubzilladaily echo "# update" >> /var/www/$hubzilladaily -echo "echo \"\$(date) - updating dehydrated...\"" >> /var/www/$hubzilladaily -echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily -echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily +echo "echo \"\$(date) - updating core and addons...\"" >> /var/www/$hubzilladaily echo "(cd /var/www/html/ ; util/udall)" >> /var/www/$hubzilladaily echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$hubzilladaily -echo "echo \"\$(date) - Backup hubzilla and update linux finished. Rebooting...\"" >> /var/www/$hubzilladaily +echo "echo \"\$(date) - Backup and update finished. Rebooting...\"" >> /var/www/$hubzilladaily echo "#" >> /var/www/$hubzilladaily -echo "reboot" >> /var/www/$hubzilladaily +echo "shutdown -r now" >> /var/www/$hubzilladaily if [ -z "`grep 'hubzilla-daily.sh' /etc/crontab`" ] then @@ -745,38 +621,6 @@ echo "reboot" >> /var/www/$hubzilladaily print_info "configured cron for updates/upgrades" } -function write_uninstall_script { - print_info "writing uninstall script..." - - cat > /var/www/hubzilla-remove.sh < 'Image', 'id' => $x['id'], 'name' => $x['title'], - 'content' => bbcode($x['body']), + 'content' => bbcode($x['body'], [ 'cache' => true ]), 'source' => [ 'mediaType' => 'text/bbcode', 'content' => $x['body'] ], 'published' => datetime_convert('UTC','UTC',$x['created'],ATOM_TIME), 'updated' => datetime_convert('UTC','UTC', $x['edited'],ATOM_TIME), @@ -181,14 +186,24 @@ class Activity { $y = [ 'type' => 'Event', 'id' => z_root() . '/event/' . $ev['event_hash'], - 'summary' => bbcode($ev['summary']), + 'summary' => bbcode($ev['summary'], [ 'cache' => true ]), // RFC3339 Section 4.3 'startTime' => (($ev['adjust']) ? datetime_convert('UTC','UTC',$ev['dtstart'], ATOM_TIME) : datetime_convert('UTC','UTC',$ev['dtstart'],'Y-m-d\\TH:i:s-00:00')), - 'content' => bbcode($ev['description']), - 'location' => [ 'type' => 'Place', 'content' => bbcode($ev['location']) ], + 'content' => bbcode($ev['description'], [ 'cache' => true ]), + 'location' => [ 'type' => 'Place', 'content' => bbcode($ev['location'], [ 'cache' => true ]) ], 'source' => [ 'content' => format_event_bbcode($ev), 'mediaType' => 'text/bbcode' ], 'actor' => $actor, ]; + if(! $ev['nofinish']) { + $y['endTime'] = (($ev['adjust']) ? datetime_convert('UTC','UTC',$ev['dtend'], ATOM_TIME) : datetime_convert('UTC','UTC',$ev['dtend'],'Y-m-d\\TH:i:s-00:00')); + } + + // copy attachments from the passed object - these are already formatted for ActivityStreams + + if($x['attachment']) { + $y['attachment'] = $x['attachment']; + } + if($actor) { return $y; } @@ -279,8 +294,12 @@ class Activity { $ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME); if($i['created'] !== $i['edited']) $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); + if ($i['expires'] <= NULL_DATE) { + $ret['expires'] = datetime_convert('UTC','UTC',$i['expires'],ATOM_TIME); + } + if($i['app']) { - $ret['instrument'] = [ 'type' => 'Service', 'name' => $i['app'] ]; + $ret['generator'] = [ 'type' => 'Application', 'name' => $i['app'] ]; } if($i['location'] || $i['coord']) { $ret['location'] = [ 'type' => 'Place' ]; @@ -297,15 +316,15 @@ class Activity { $ret['attributedTo'] = $i['author']['xchan_url']; if($i['id'] != $i['parent']) { - $ret['inReplyTo'] = ((strpos($i['parent_mid'],'http') === 0) ? $i['parent_mid'] : z_root() . '/item/' . urlencode($i['parent_mid'])); + $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); } if($i['mimetype'] === 'text/bbcode') { if($i['title']) - $ret['name'] = bbcode($i['title']); + $ret['name'] = bbcode($i['title'], [ 'cache' => true ]); if($i['summary']) - $ret['summary'] = bbcode($i['summary']); - $ret['content'] = bbcode($i['body']); + $ret['summary'] = bbcode($i['summary'], [ 'cache' => true ]); + $ret['content'] = bbcode($i['body'], [ 'cache' => true ]); $ret['source'] = [ 'content' => $i['body'], 'mediaType' => 'text/bbcode' ]; } @@ -398,7 +417,7 @@ class Activity { $ret = []; if($item['attach']) { - $atts = json_decode($item['attach'],true); + $atts = ((is_array($item['attach'])) ? $item['attach'] : json_decode($item['attach'],true)); if($atts) { foreach($atts as $att) { if(strpos($att['type'],'image')) { @@ -410,7 +429,7 @@ class Activity { } } } - + return $ret; } @@ -457,20 +476,26 @@ class Activity { return $ret; } + if($i['verb'] === ACTIVITY_FRIEND) { + // Hubzilla 'make-friend' activity, no direct mapping from AS1 to AS2 - make it a note + $ret['obj_type'] = ACTIVITY_OBJ_NOTE; + $ret['obj'] = []; + } + $ret['type'] = self::activity_mapper($i['verb']); $ret['id'] = ((strpos($i['mid'],'http') === 0) ? $i['mid'] : z_root() . '/activity/' . urlencode($i['mid'])); if($i['title']) - $ret['name'] = html2plain(bbcode($i['title'])); + $ret['name'] = html2plain(bbcode($i['title'], [ 'cache' => true ])); if($i['summary']) - $ret['summary'] = bbcode($i['summary']); + $ret['summary'] = bbcode($i['summary'], [ 'cache' => true ]); if($ret['type'] === 'Announce') { $tmp = preg_replace('/\[share(.*?)\[\/share\]/ism',EMPTY_STR, $i['body']); - $ret['content'] = bbcode($tmp); + $ret['content'] = bbcode($tmp, [ 'cache' => true ]); $ret['source'] = [ 'content' => $i['body'], 'mediaType' => 'text/bbcode' @@ -481,7 +506,7 @@ class Activity { if($i['created'] !== $i['edited']) $ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME); if($i['app']) { - $ret['instrument'] = [ 'type' => 'Service', 'name' => $i['app'] ]; + $ret['generator'] = [ 'type' => 'Application', 'name' => $i['app'] ]; } if($i['location'] || $i['coord']) { $ret['location'] = [ 'type' => 'Place' ]; @@ -496,7 +521,7 @@ class Activity { } if($i['id'] != $i['parent']) { - $ret['inReplyTo'] = ((strpos($i['parent_mid'],'http') === 0) ? $i['parent_mid'] : z_root() . '/item/' . urlencode($i['parent_mid'])); + $ret['inReplyTo'] = ((strpos($i['thr_parent'],'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); $reply = true; if($i['item_private']) { @@ -553,6 +578,7 @@ class Activity { return []; } + if($i['target']) { if(! is_array($i['target'])) { $i['target'] = json_decode($i['target'],true); @@ -697,7 +723,7 @@ class Activity { // Reactions will just map to normal activities if(strpos($verb,ACTIVITY_REACT) !== false) - return 'Create'; + return 'emojiReaction'; if(strpos($verb,ACTIVITY_MOOD) !== false) return 'Create'; @@ -1287,6 +1313,12 @@ class Activity { elseif($act->obj['updated']) { $s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']); } + if ($act->data['expires']) { + $s['expires'] = datetime_convert('UTC','UTC',$act->data['expires']); + } + elseif ($act->obj['expires']) { + $s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']); + } if(! $s['created']) $s['created'] = datetime_convert(); @@ -1305,13 +1337,13 @@ class Activity { $s['verb'] = ACTIVITY_POST; $s['obj_type'] = ACTIVITY_OBJ_NOTE; - $instrument = $act->get_property_obj('instrument'); - if(! $instrument) - $instrument = $act->get_property_obj('instrument',$act->obj); + $generator = $act->get_property_obj('generator'); + if(! $generator) + $generator = $act->get_property_obj('generator',$act->obj); - if($instrument && array_key_exists('type',$instrument) - && $instrument['type'] === 'Service' && array_key_exists('name',$instrument)) { - $s['app'] = escape_tags($instrument['name']); + if($generator && array_key_exists('type',$generator) + && in_array($generator['type'], [ 'Application','Service' ] ) && array_key_exists('name',$generator)) { + $s['app'] = escape_tags($generator['name']); } if($channel['channel_system']) { @@ -1471,9 +1503,15 @@ class Activity { elseif($act->obj['updated']) { $s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']); } + if ($act->data['expires']) { + $s['expires'] = datetime_convert('UTC','UTC',$act->data['expires']); + } + elseif ($act->obj['expires']) { + $s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']); + } - if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept' ])) { + if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'emojiReaction' ])) { $response_activity = true; @@ -1514,6 +1552,9 @@ class Activity { if($act->type === 'Announce') { $content['content'] = sprintf( t('🔁 Repeated %1$s\'s %2$s'), $mention, $act->obj['type']); } + if ($act->type === 'emojiReaction') { + $content['content'] = (($act->tgt && $act->tgt['type'] === 'Image') ? '[img=32x32]' . $act->tgt['url'] . '[/img]' : '&#x' . $act->tgt['name'] . ';'); + } } if(! $s['created']) @@ -1565,14 +1606,14 @@ class Activity { $s['obj'] = $act->obj; } - $instrument = $act->get_property_obj('instrument'); - if((! $instrument) && (! $response_activity)) { - $instrument = $act->get_property_obj('instrument',$act->obj); + $generator = $act->get_property_obj('generator'); + if((! $generator) && (! $response_activity)) { + $generator = $act->get_property_obj('generator',$act->obj); } - if($instrument && array_key_exists('type',$instrument) - && $instrument['type'] === 'Service' && array_key_exists('name',$instrument)) { - $s['app'] = escape_tags($instrument['name']); + if($generator && array_key_exists('type',$generator) + && in_array($generator['type'], [ 'Application', 'Service' ] ) && array_key_exists('name',$generator)) { + $s['app'] = escape_tags($generator['name']); } diff --git a/Zotlabs/Lib/Apps.php b/Zotlabs/Lib/Apps.php index fefc6639d..69996b49d 100644 --- a/Zotlabs/Lib/Apps.php +++ b/Zotlabs/Lib/Apps.php @@ -70,7 +70,7 @@ class Apps { 'Channel Home', 'View Profile', 'Photos', - 'Events', + 'Calendar', 'Directory', 'Search', 'Help', @@ -342,7 +342,7 @@ class Apps { 'Channel Home' => t('Channel Home'), 'View Profile' => t('View Profile'), 'Photos' => t('Photos'), - 'Events' => t('Events'), + 'Calendar' => t('Calendar'), 'Directory' => t('Directory'), 'Help' => t('Help'), 'Mail' => t('Mail'), @@ -363,7 +363,6 @@ class Apps { 'Privacy Groups' => t('Privacy Groups'), 'Notifications' => t('Notifications'), 'Order Apps' => t('Order Apps'), - 'CalDAV' => t('CalDAV'), 'CardDAV' => t('CardDAV'), 'Channel Sources' => t('Channel Sources'), 'Guest Access' => t('Guest Access'), diff --git a/Zotlabs/Lib/DB_Upgrade.php b/Zotlabs/Lib/DB_Upgrade.php index 4038a2d53..b6e3f7b7b 100644 --- a/Zotlabs/Lib/DB_Upgrade.php +++ b/Zotlabs/Lib/DB_Upgrade.php @@ -58,10 +58,15 @@ class DB_Upgrade { $c = new $cls(); + $retval = $c->run(); if($retval != UPDATE_SUCCESS) { + + $source = t('Source code of failed update: ') . "\n\n" . @file_get_contents('Zotlabs/Update/' . $s . '.php'); + + // Prevent sending hundreds of thousands of emails by creating // a lockfile. @@ -86,7 +91,9 @@ class DB_Upgrade { '$sitename' => \App::$config['system']['sitename'], '$siteurl' => z_root(), '$update' => $x, - '$error' => sprintf( t('Update %s failed. See error logs.'), $x) + '$error' => sprintf( t('Update %s failed. See error logs.'), $x), + '$baseurl' => z_root(), + '$source' => $source ] ) ] diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 9bf987027..976ed22fa 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -2766,7 +2766,7 @@ class Libzot { $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; - if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== '')) + if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],'UTC')) !== '')) $profile['next_birthday'] = $bd; if($age = age($p[0]['dob'],$e['channel_timezone'],'')) diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 40c0fca4b..9161aa182 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -38,6 +38,7 @@ class ThreadItem { $this->data = $data; $this->toplevel = ($this->get_id() == $this->get_data_value('parent')); + $this->threaded = get_config('system','thread_allow'); $observer = \App::get_observer(); @@ -305,6 +306,7 @@ class ThreadItem { if($this->is_commentable() && $observer) { $like = array( t("I like this \x28toggle\x29"), t("like")); $dislike = array( t("I don't like this \x28toggle\x29"), t("dislike")); + $reply_to = array( t("Reply on this comment"), t("reply"), t("Reply to")); } if ($shareable) { @@ -331,7 +333,6 @@ class ThreadItem { if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0) $is_new = true; - localize_item($item); $body = prepare_body($item,true); @@ -347,10 +348,6 @@ class ThreadItem { $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); $list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : ''); - - - - $children = $this->get_children(); $has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false); @@ -373,13 +370,15 @@ class ThreadItem { 'text' => strip_tags($body['html']), 'id' => $this->get_id(), 'mid' => $item['mid'], + 'parent' => $item['parent'], + 'author_id' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']), 'isevent' => $isevent, 'attend' => $attend, 'consensus' => $consensus, 'conlabels' => $conlabels, 'canvote' => $canvote, - 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']), - 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']), + 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url'])), + 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), (($item['owner']['xchan_addr']) ? $item['owner']['xchan_addr'] : $item['owner']['xchan_url'])), 'llink' => $item['llink'], 'viewthread' => $viewthread, 'to' => t('to'), @@ -425,9 +424,11 @@ class ThreadItem { 'has_tags' => $has_tags, 'reactions' => $this->reactions, // Item toolbar buttons - 'emojis' => (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''), + 'emojis' => (($this->is_toplevel() && $this->is_commentable() && $observer && feature_enabled($conv->get_profile_owner(),'emojis')) ? '1' : ''), 'like' => $like, 'dislike' => ((feature_enabled($conv->get_profile_owner(),'dislike')) ? $dislike : ''), + 'reply_to' => (((! $this->is_toplevel()) && feature_enabled($conv->get_profile_owner(),'reply_to')) ? $reply_to : ''), + 'top_hint' => t("Go to previous comment"), 'share' => $share, 'embed' => $embed, 'rawmid' => $item['mid'], @@ -440,9 +441,8 @@ class ThreadItem { 'addtocal' => (($has_event) ? t('Add to Calendar') : ''), 'drop' => $drop, 'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''), - 'dropdown_extras' => $dropdown_extras, + 'dropdown_extras' => $dropdown_extras, // end toolbar buttons - 'unseen_comments' => $unseen_comments, 'comment_count' => $total_children, 'comment_count_txt' => $comment_count_txt, @@ -469,7 +469,8 @@ class ThreadItem { 'wait' => t('Please wait'), 'submid' => str_replace(['+','='], ['',''], base64_encode($item['mid'])), 'thread_level' => $thread_level, - 'settings' => $settings + 'settings' => $settings, + 'thr_parent' => (($item['parent_mid'] != $item['thr_parent']) ? $item['thr_parent'] : '') ); $arr = array('item' => $item, 'output' => $tmp_item); @@ -814,7 +815,7 @@ class ThreadItem { '$anonname' => [ 'anonname', t('Your full name (required)') ], '$anonmail' => [ 'anonmail', t('Your email address (required)') ], '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ], - '$auto_save_draft' => $feature_auto_save_draft, + '$auto_save_draft' => $feature_auto_save_draft )); return $comment_box; @@ -869,4 +870,3 @@ class ThreadItem { } - diff --git a/Zotlabs/Module/Admin/Dbsync.php b/Zotlabs/Module/Admin/Dbsync.php index 469af2aa5..183834301 100644 --- a/Zotlabs/Module/Admin/Dbsync.php +++ b/Zotlabs/Module/Admin/Dbsync.php @@ -19,7 +19,47 @@ class Dbsync { info( t('Update has been marked successful') . EOL); goaway(z_root() . '/admin/dbsync'); } + + if(argc() > 3 && intval(argv(3)) && argv(2) === 'verify') { + + $s = '_' . intval(argv(3)); + $cls = '\\Zotlabs\Update\\' . $s ; + if(class_exists($cls)) { + $c = new $cls(); + if(method_exists($c,'verify')) { + $retval = $c->verify(); + if($retval === UPDATE_FAILED) { + $o .= sprintf( t('Verification of update %s failed. Check system logs.'), $s); + } + elseif($retval === UPDATE_SUCCESS) { + $o .= sprintf( t('Update %s was successfully applied.'), $s); + set_config('database',$s, 'success'); + } + else + $o .= sprintf( t('Verifying update %s did not return a status. Unknown if it succeeded.'), $s); + } + else { + $o .= sprintf( t('Update %s does not contain a verification function.'), $s ); + } + } + else + $o .= sprintf( t('Update function %s could not be found.'), $s); + return $o; + + + + + + // remove the old style config if it exists + del_config('database', 'update_r' . intval(argv(3))); + set_config('database', '_' . intval(argv(3)), 'success'); + if(intval(get_config('system','db_version')) < intval(argv(3))) + set_config('system','db_version',intval(argv(3))); + info( t('Update has been marked successful') . EOL); + goaway(z_root() . '/admin/dbsync'); + } + if(argc() > 2 && intval(argv(2))) { $x = intval(argv(2)); $s = '_' . $x; @@ -28,14 +68,14 @@ class Dbsync { $c = new $cls(); $retval = $c->run(); if($retval === UPDATE_FAILED) { - $o .= sprintf( t('Executing %s failed. Check system logs.'), $s); + $o .= sprintf( t('Executing update procedure %s failed. Check system logs.'), $s); } elseif($retval === UPDATE_SUCCESS) { $o .= sprintf( t('Update %s was successfully applied.'), $s); set_config('database',$s, 'success'); } else - $o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $s); + $o .= sprintf( t('Update %s did not return a status. It cannot be determined if it was successful.'), $s); } else $o .= sprintf( t('Update function %s could not be found.'), $s); @@ -59,6 +99,7 @@ class Dbsync { '$banner' => t('Failed Updates'), '$desc' => '', '$mark' => t('Mark success (if update was manually applied)'), + '$verify' => t('Attempt to verify this update if a verification procedure exists'), '$apply' => t('Attempt to execute this update step automatically'), '$failed' => $failed )); diff --git a/Zotlabs/Module/Apschema.php b/Zotlabs/Module/Apschema.php new file mode 100644 index 000000000..d217041f2 --- /dev/null +++ b/Zotlabs/Module/Apschema.php @@ -0,0 +1,57 @@ + [ + 'zot' => z_root() . '/apschema#', + 'id' => '@id', + 'type' => '@type', + 'commentPolicy' => 'as:commentPolicy', + 'meData' => 'zot:meData', + 'meDataType' => 'zot:meDataType', + 'meEncoding' => 'zot:meEncoding', + 'meAlgorithm' => 'zot:meAlgorithm', + 'meCreator' => 'zot:meCreator', + 'meSignatureValue' => 'zot:meSignatureValue', + 'locationAddress' => 'zot:locationAddress', + 'locationPrimary' => 'zot:locationPrimary', + 'locationDeleted' => 'zot:locationDeleted', + 'nomadicLocation' => 'zot:nomadicLocation', + 'nomadicHubs' => 'zot:nomadicHubs', + 'emojiReaction' => 'zot:emojiReaction', + 'expires' => 'zot:expires', + + 'magicEnv' => [ + '@id' => 'zot:magicEnv', + '@type' => '@id' + ], + + 'nomadicLocations' => [ + '@id' => 'zot:nomadicLocations', + '@type' => '@id' + ], + + 'ostatus' => 'http://ostatus.org#', + 'conversation' => 'ostatus:conversation' + + ] + ]; + + header('Content-Type: application/ld+json'); + echo json_encode($arr,JSON_UNESCAPED_SLASHES); + killme(); + + } + + + + +} \ No newline at end of file diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php index 70098a2a1..49489f912 100644 --- a/Zotlabs/Module/Cal.php +++ b/Zotlabs/Module/Cal.php @@ -84,6 +84,7 @@ class Cal extends \Zotlabs\Web\Controller { '$module_url' => '/cal/' . $channel['channel_address'], '$modparams' => 2, '$lang' => \App::$language, + '$timezone' => date_default_timezone_get(), '$first_day' => $first_day )); @@ -215,8 +216,8 @@ class Cal extends \Zotlabs\Web\Controller { $sql_extra .= " and etype != 'birthday' "; if (x($_GET,'id')){ - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan - from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1", + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + from event left join item on resource_id = event_hash where resource_type = 'event' and event.uid = %d and event.id = %d $sql_extra limit 1", intval($channel['channel_id']), intval($_GET['id']) ); @@ -227,12 +228,12 @@ class Cal extends \Zotlabs\Web\Controller { // Noting this for now - it will need to be fixed here and in Friendica. // Ultimately the finish date shouldn't be involved in the query. - $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan - from event left join item on event_hash = resource_id - where resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored - AND (( adjust = 0 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' ) - OR ( adjust = 1 AND ( dtend >= '%s' or nofinish = 1 ) AND dtstart <= '%s' )) $sql_extra ", - intval($channel['channel_id']), + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + from event left join item on event.event_hash = item.resource_id + where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored + AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ) + OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )) ", + intval(local_channel()), dbesc($start), dbesc($finish), dbesc($adjust_start), @@ -266,16 +267,23 @@ class Cal extends \Zotlabs\Web\Controller { if($r) { foreach($r as $rr) { - - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); - $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt)); + + $tz = get_iconfig($rr, 'event', 'timezone'); + + if(! $tz) + $tz = 'UTC'; + + $rr['timezone'] = $tz; + + $j = (($rr['adjust']) ? datetime_convert($tz,date_default_timezone_get(),$rr['dtstart'], 'j') : datetime_convert('UTC','UTC',$rr['dtstart'],'j')); + $d = (($rr['adjust']) ? datetime_convert($tz,date_default_timezone_get(),$rr['dtstart'], $fmt) : datetime_convert('UTC','UTC',$rr['dtstart'],$fmt)); $d = day_translate($d); - $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c')); + $start = (($rr['adjust']) ? datetime_convert($tz,date_default_timezone_get(),$rr['dtstart'], 'c') : datetime_convert('UTC','UTC',$rr['dtstart'],'c')); if ($rr['nofinish']){ $end = null; } else { - $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c')); + $end = (($rr['adjust']) ? datetime_convert($tz,date_default_timezone_get(),$rr['dtend'], 'c') : datetime_convert('UTC','UTC',$rr['dtend'],'c')); } @@ -302,7 +310,7 @@ class Cal extends \Zotlabs\Web\Controller { 'start'=> $start, 'end' => $end, 'drop' => $drop, - 'allDay' => false, + 'allDay' => (($rr['adjust']) ? 0 : 1), 'title' => $title, 'j' => $j, diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index 5dd233d28..de639e281 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -133,10 +133,6 @@ class Cdav extends Controller { logger('loggedin'); - if((argv(1) == 'calendars') && (!Apps::system_app_installed(local_channel(), 'CalDAV'))) { - killme(); - } - if((argv(1) == 'addressbooks') && (!Apps::system_app_installed(local_channel(), 'CardDAV'))) { killme(); } @@ -221,10 +217,6 @@ class Cdav extends Controller { if(! local_channel()) return; - if((argv(1) === 'calendar') && (! Apps::system_app_installed(local_channel(), 'CalDAV'))) { - return; - } - if((argv(1) === 'addressbook') && (! Apps::system_app_installed(local_channel(), 'CardDAV'))) { return; } @@ -279,11 +271,17 @@ class Cdav extends Controller { if(!cdav_perms($id[0],$calendars,true)) return; + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); + $tz = (($timezone) ? $timezone : date_default_timezone_get()); + + $allday = $_REQUEST['allday']; + $title = $_REQUEST['title']; - $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']); + $start = datetime_convert($tz, 'UTC', $_REQUEST['dtstart']); $dtstart = new \DateTime($start); + if($_REQUEST['dtend']) { - $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']); + $end = datetime_convert($tz, 'UTC', $_REQUEST['dtend']); $dtend = new \DateTime($end); } $description = $_REQUEST['description']; @@ -309,16 +307,23 @@ class Cdav extends Controller { 'DTSTART' => $dtstart ] ]); + if($dtend) { $vcalendar->VEVENT->add('DTEND', $dtend); - $vcalendar->VEVENT->DTEND['TZID'] = App::$timezone; + if($allday) + $vcalendar->VEVENT->DTEND['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTEND['TZID'] = $tz; } if($description) $vcalendar->VEVENT->add('DESCRIPTION', $description); if($location) $vcalendar->VEVENT->add('LOCATION', $location); - $vcalendar->VEVENT->DTSTART['TZID'] = App::$timezone; + if($allday) + $vcalendar->VEVENT->DTSTART['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTSTART['TZID'] = $tz; $calendarData = $vcalendar->serialize(); @@ -356,12 +361,17 @@ class Cdav extends Controller { if(!cdav_perms($id[0],$calendars,true)) return; + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); + $tz = (($timezone) ? $timezone : date_default_timezone_get()); + + $allday = $_REQUEST['allday']; + $uri = $_REQUEST['uri']; $title = $_REQUEST['title']; - $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']); + $start = datetime_convert($tz, 'UTC', $_REQUEST['dtstart']); $dtstart = new \DateTime($start); if($_REQUEST['dtend']) { - $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']); + $end = datetime_convert($tz, 'UTC', $_REQUEST['dtend']); $dtend = new \DateTime($end); } $description = $_REQUEST['description']; @@ -373,12 +383,23 @@ class Cdav extends Controller { if($title) $vcalendar->VEVENT->SUMMARY = $title; - if($dtstart) + if($dtstart) { $vcalendar->VEVENT->DTSTART = $dtstart; - if($dtend) + if($allday) + $vcalendar->VEVENT->DTSTART['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTSTART['TZID'] = $tz; + } + if($dtend) { $vcalendar->VEVENT->DTEND = $dtend; + if($allday) + $vcalendar->VEVENT->DTEND['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTEND['TZID'] = $tz; + } else unset($vcalendar->VEVENT->DTEND); + if($description) $vcalendar->VEVENT->DESCRIPTION = $description; if($location) @@ -414,11 +435,16 @@ class Cdav extends Controller { if(!cdav_perms($id[0],$calendars,true)) return; + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); + $tz = (($timezone) ? $timezone : date_default_timezone_get()); + + $allday = $_REQUEST['allday']; + $uri = $_REQUEST['uri']; - $start = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtstart']); + $start = datetime_convert($tz, 'UTC', $_REQUEST['dtstart']); $dtstart = new \DateTime($start); if($_REQUEST['dtend']) { - $end = datetime_convert(App::$timezone, 'UTC', $_REQUEST['dtend']); + $end = datetime_convert($tz, 'UTC', $_REQUEST['dtend']); $dtend = new \DateTime($end); } @@ -428,13 +454,20 @@ class Cdav extends Controller { if($dtstart) { $vcalendar->VEVENT->DTSTART = $dtstart; + if($allday) + $vcalendar->VEVENT->DTSTART['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTSTART['TZID'] = $tz; } if($dtend) { $vcalendar->VEVENT->DTEND = $dtend; + if($allday) + $vcalendar->VEVENT->DTEND['VALUE'] = 'DATE'; + else + $vcalendar->VEVENT->DTEND['TZID'] = $tz; } - else { + else unset($vcalendar->VEVENT->DTEND); - } $calendarData = $vcalendar->serialize(); @@ -762,16 +795,27 @@ class Cdav extends Controller { //Import calendar or addressbook if(($_FILES) && array_key_exists('userfile',$_FILES) && intval($_FILES['userfile']['size']) && $_REQUEST['target']) { - $src = @file_get_contents($_FILES['userfile']['tmp_name']); + $src = $_FILES['userfile']['tmp_name']; if($src) { if($_REQUEST['c_upload']) { + if($_REQUEST['target'] == 'channel_calendar') { + $result = parse_ical_file($src,local_channel()); + if($result) + info( t('Calendar entries imported.') . EOL); + else + notice( t('No calendar entries found.') . EOL); + + @unlink($src); + return; + } + $id = explode(':', $_REQUEST['target']); $ext = 'ics'; $table = 'calendarobjects'; $column = 'calendarid'; - $objects = new \Sabre\VObject\Splitter\ICalendar($src); + $objects = new \Sabre\VObject\Splitter\ICalendar(@file_get_contents($src)); $profile = \Sabre\VObject\Node::PROFILE_CALDAV; $backend = new \Sabre\CalDAV\Backend\PDO($pdo); } @@ -781,7 +825,7 @@ class Cdav extends Controller { $ext = 'vcf'; $table = 'cards'; $column = 'addressbookid'; - $objects = new \Sabre\VObject\Splitter\VCard($src); + $objects = new \Sabre\VObject\Splitter\VCard(@file_get_contents($src)); $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; $backend = new \Sabre\CardDAV\Backend\PDO($pdo); } @@ -847,15 +891,6 @@ class Cdav extends Controller { if(!local_channel()) return; - if((argv(1) === 'calendar') && (! Apps::system_app_installed(local_channel(), 'CalDAV'))) { - //Do not display any associated widgets at this point - App::$pdl = ''; - - $o = '' . t('CalDAV App') . ' (' . t('Not Installed') . '):
'; - $o .= t('CalDAV capable calendar'); - return $o; - } - if((argv(1) === 'addressbook') && (! Apps::system_app_installed(local_channel(), 'CardDAV'))) { //Do not display any associated widgets at this point App::$pdl = ''; @@ -884,13 +919,13 @@ class Cdav extends Controller { } if(argv(1) === 'calendar') { - nav_set_selected('CalDAV'); + nav_set_selected('Calendar'); $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $calendars = $caldavBackend->getCalendarsForUser($principalUri); } //Display calendar(s) here - if(argc() == 2 && argv(1) === 'calendar') { + if(argc() <= 3 && argv(1) === 'calendar') { head_add_css('/library/fullcalendar/packages/core/main.min.css'); head_add_css('/library/fullcalendar/packages/daygrid/main.min.css'); @@ -905,10 +940,72 @@ class Cdav extends Controller { head_add_js('/library/fullcalendar/packages/list/main.min.js'); $sources = ''; + $resource_id = ''; + $resource = null; + + if(argc() == 3) + $resource_id = argv(2); + + if($resource_id) { + $r = q("SELECT event.*, item.author_xchan, item.owner_xchan, item.plink, item.id as item_id FROM event LEFT JOIN item ON event.event_hash = item.resource_id + WHERE event.uid = %d AND event.event_hash = '%s' LIMIT 1", + intval(local_channel()), + dbesc($resource_id) + ); + if($r) { + xchan_query($r); + $r = fetch_post_tags($r,true); + + $tz = get_iconfig($r[0], 'event', 'timezone'); + if(! $tz) + $tz = 'UTC'; + + $r[0]['timezone'] = $tz; + $r[0]['dtstart'] = (($r[0]['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $r[0]['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $r[0]['dtstart'], 'c')); + $r[0]['dtend'] = (($r[0]['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $r[0]['dtend'], 'c') : datetime_convert('UTC', 'UTC' ,$r[0]['dtend'], 'c')); + + $r[0]['plink'] = [$r[0]['plink'], t('Link to source')]; + + $resource = $r[0]; + + $catsenabled = feature_enabled(local_channel(),'categories'); + $categories = ''; + if($catsenabled){ + if($r[0]['term']) { + $cats = get_terms_oftype($r[0]['term'], TERM_CATEGORY); + foreach ($cats as $cat) { + if(strlen($categories)) + $categories .= ', '; + $categories .= $cat['term']; + } + } + } + + if($r[0]['dismissed'] == 0) { + q("UPDATE event SET dismissed = 1 WHERE event.uid = %d AND event.event_hash = '%s'", + intval(local_channel()), + dbesc($resource_id) + ); + } + } + } + + if(get_pconfig(local_channel(), 'cdav_calendar', 'channel_calendar')) { + $sources .= '{ + id: \'channel_calendar\', + url: \'/channel_calendar/json/\', + color: \'#3a87ad\' + }, '; + } + + $channel_calendars[] = [ + 'displayname' => $channel['channel_name'], + 'id' => 'channel_calendar' + ]; foreach($calendars as $calendar) { $editable = (($calendar['share-access'] == 2) ? 'false' : 'true'); // false/true must be string since we're passing it to javascript - $color = (($calendar['{http://apple.com/ns/ical/}calendar-color']) ? $calendar['{http://apple.com/ns/ical/}calendar-color'] : '#3a87ad'); + $color = (($calendar['{http://apple.com/ns/ical/}calendar-color']) ? $calendar['{http://apple.com/ns/ical/}calendar-color'] : '#6cad39'); $sharer = (($calendar['share-access'] == 3) ? $calendar['{urn:ietf:params:xml:ns:caldav}calendar-description'] : ''); $switch = get_pconfig(local_channel(), 'cdav_calendar', $calendar['id'][0]); if($switch) { @@ -933,17 +1030,31 @@ class Cdav extends Controller { $first_day = feature_enabled(local_channel(), 'cal_first_day'); $first_day = (($first_day) ? $first_day : 0); - $title = ['title', t('Event title')]; + $title = ['title', t('Event title') ]; $dtstart = ['dtstart', t('Start date and time')]; $dtend = ['dtend', t('End date and time')]; + $timezone_select = ['timezone_select' , t('Timezone:'), date_default_timezone_get(), '', get_timezones()]; + $description = ['description', t('Description')]; $location = ['location', t('Location')]; + $catsenabled = feature_enabled(local_channel(), 'categories'); + + require_once('include/acl_selectors.php'); + + $accesslist = new \Zotlabs\Access\AccessList($channel); + $perm_defaults = $accesslist->get(); + + //$acl = (($orig_event['event_xchan']) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $perm_defaults), false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'))); + $acl = populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream')); + + $permissions = (($resource_id) ? $resource : $perm_defaults); + $o .= replace_macros(get_markup_template('cdav_calendar.tpl'), [ '$sources' => $sources, '$color' => $color, '$lang' => App::$language, - '$timezone' => App::$timezone, + '$timezone' => date_default_timezone_get(), '$first_day' => $first_day, '$prev' => t('Previous'), '$next' => t('Next'), @@ -955,6 +1066,7 @@ class Cdav extends Controller { '$list_week' => t('List week'), '$list_day' => t('List day'), '$title' => $title, + '$channel_calendars' => $channel_calendars, '$writable_calendars' => $writable_calendars, '$dtstart' => $dtstart, '$dtend' => $dtend, @@ -962,11 +1074,28 @@ class Cdav extends Controller { '$location' => $location, '$more' => t('More'), '$less' => t('Less'), + '$update' => t('Update'), '$calendar_select_label' => t('Select calendar'), + '$calendar_optiopns_label' => [t('Channel Calendars'), t('CalDAV Calendars')], '$delete' => t('Delete'), '$delete_all' => t('Delete all'), '$cancel' => t('Cancel'), - '$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.') + '$create' => t('Create'), + '$recurrence_warning' => t('Sorry! Editing of recurrent events is not yet implemented.'), + + '$channel_hash' => $channel['channel_hash'], + '$acl' => $acl, + '$lockstate' => (($accesslist->is_private()) ? 'lock' : 'unlock'), + '$allow_cid' => acl2json($permissions['allow_cid']), + '$allow_gid' => acl2json($permissions['allow_gid']), + '$deny_cid' => acl2json($permissions['deny_cid']), + '$deny_gid' => acl2json($permissions['deny_gid']), + '$catsenabled' => $catsenabled, + '$categories_label' => t('Categories'), + + '$resource' => json_encode($resource), + '$categories' => $categories, + '$timezone_select' => ((feature_enabled(local_channel(),'event_tz_select')) ? $timezone_select : '') ]); return $o; @@ -995,8 +1124,8 @@ class Cdav extends Controller { $filters['comp-filters'][0]['time-range']['end'] = $end; $uris = $caldavBackend->calendarQuery($id, $filters); - if($uris) { + $objects = $caldavBackend->getMultipleCalendarObjects($id, $uris); foreach($objects as $object) { @@ -1015,30 +1144,33 @@ class Cdav extends Controller { $dtend = (string)$vevent->DTEND; $description = (string)$vevent->DESCRIPTION; $location = (string)$vevent->LOCATION; - $timezone = (string)$vevent->DTSTART['TZID']; + $timezone_str = (string)$vevent->DTSTART['TZID']; $rw = ((cdav_perms($id[0],$calendars,true)) ? true : false); $editable = $rw ? true : false; $recurrent = ((isset($vevent->{'RECURRENCE-ID'})) ? true : false); if($recurrent) { $editable = false; - $timezone = $recurrent_timezone; + $timezone_str = $recurrent_timezone; } - $allDay = false; + // Try to get an usable olson format timezone + $timezone_obj = \Sabre\VObject\TimeZoneUtil::getTimeZone($timezone_str, $vcalendar); + $timezone = $timezone_obj->getName(); - // allDay event rules - if(!strpos($dtstart, 'T') && !strpos($dtend, 'T')) - $allDay = true; - if(strpos($dtstart, 'T000000') && strpos($dtend, 'T000000')) - $allDay = true; + // If we got nothing fallback to UTC + if(! $timezone) + $timezone = 'UTC'; + + $allDay = (((string)$vevent->DTSTART['VALUE'] == 'DATE') ? true : false); $events[] = [ 'calendar_id' => $id, 'uri' => $object['uri'], 'title' => $title, - 'start' => datetime_convert($timezone, $timezone, $dtstart, 'c'), - 'end' => (($dtend) ? datetime_convert($timezone, $timezone, $dtend, 'c') : ''), + 'timezone' => $timezone, + 'start' => datetime_convert($timezone, date_default_timezone_get(), $dtstart, 'c'), + 'end' => (($dtend) ? datetime_convert($timezone, date_default_timezone_get(), $dtend, 'c') : ''), 'description' => $description, 'location' => $location, 'allDay' => $allDay, @@ -1053,7 +1185,7 @@ class Cdav extends Controller { } //enable/disable calendars - if(argc() == 5 && argv(1) === 'calendar' && argv(2) === 'switch' && intval(argv(3)) && (argv(4) == 1 || argv(4) == 0)) { + if(argc() == 5 && argv(1) === 'calendar' && argv(2) === 'switch' && argv(3) && (argv(4) == 1 || argv(4) == 0)) { $id = argv(3); if(! cdav_perms($id,$calendars)) @@ -1312,12 +1444,13 @@ class Cdav extends Controller { $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); $properties = [ '{DAV:}displayname' => t('Default Calendar'), - '{http://apple.com/ns/ical/}calendar-color' => '#3a87ad', + '{http://apple.com/ns/ical/}calendar-color' => '#6cad39', '{urn:ietf:params:xml:ns:caldav}calendar-description' => $channel['channel_name'] ]; $id = $caldavBackend->createCalendar($uri, 'default', $properties); set_pconfig(local_channel(), 'cdav_calendar' , $id[0], 1); + set_pconfig(local_channel(), 'cdav_calendar' , 'channel_calendar', 1); //create default addressbook $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php index d4ef94e06..144c2472a 100644 --- a/Zotlabs/Module/Channel.php +++ b/Zotlabs/Module/Channel.php @@ -46,14 +46,14 @@ class Channel extends Controller { $channel = App::get_channel(); if((local_channel()) && (argc() > 2) && (argv(2) === 'view')) { - $which = $channel['channel_address']; - $profile = argv(1); - } + $which = $channel['channel_address']; + $profile = argv(1); + } $channel = channelx_by_nick($which); - if(! $channel) { - http_status_exit(404, 'Not found'); - } + if(! $channel) { + http_status_exit(404, 'Not found'); + } // handle zot6 channel discovery @@ -310,10 +310,6 @@ class Channel extends Controller { $sql_extra2 .= protect_sprintf(sprintf(" AND item.created >= '%s' ", dbesc(datetime_convert(date_default_timezone_get(),'',$datequery2)))); } - if($datequery || $datequery2) { - $sql_extra2 .= " and item.item_thread_top != 0 "; - } - if($order === 'post') $ordering = "created"; else @@ -342,7 +338,7 @@ class Channel extends Controller { AND (abook.abook_blocked = 0 or abook.abook_flags is null) AND item.item_wall = 1 AND item.item_thread_top = 1 $sql_extra $sql_extra2 - ORDER BY $ordering DESC $pager_sql ", + ORDER BY $ordering DESC, item_id $pager_sql ", intval(App::$profile['profile_uid']) ); } diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php new file mode 100644 index 000000000..4f08eb27c --- /dev/null +++ b/Zotlabs/Module/Channel_calendar.php @@ -0,0 +1,441 @@ +set($x[0]); + + $created = $x[0]['created']; + $edited = datetime_convert(); + } + else { + $created = $edited = datetime_convert(); + $acl->set_from_array($_POST); + } + + $post_tags = array(); + $channel = \App::get_channel(); + $ac = $acl->get(); + + $str_contact_allow = $ac['allow_cid']; + $str_group_allow = $ac['allow_gid']; + $str_contact_deny = $ac['deny_cid']; + $str_group_deny = $ac['deny_gid']; + + $private = $acl->is_private(); + + require_once('include/text.php'); + $results = linkify_tags($desc, local_channel()); + + if($results) { + // Set permissions based on tag replacements + set_linkified_perms($results, $str_contact_allow, $str_group_allow, local_channel(), false, $private); + + foreach($results as $result) { + $success = $result['success']; + if($success['replaced']) { + $post_tags[] = array( + 'uid' => local_channel(), + 'ttype' => $success['termtype'], + 'otype' => TERM_OBJ_POST, + 'term' => $success['term'], + 'url' => $success['url'] + ); + } + } + } + + if(strlen($categories)) { + $cats = explode(',',$categories); + foreach($cats as $cat) { + $post_tags[] = array( + 'uid' => local_channel(), + 'ttype' => TERM_CATEGORY, + 'otype' => TERM_OBJ_POST, + 'term' => trim($cat), + 'url' => $channel['xchan_url'] . '?f=&cat=' . urlencode(trim($cat)) + ); + } + } + + $datarray = array(); + $datarray['dtstart'] = $start; + $datarray['dtend'] = $finish; + $datarray['summary'] = $summary; + $datarray['description'] = $desc; + $datarray['location'] = $location; + $datarray['etype'] = $type; + $datarray['adjust'] = $adjust; + $datarray['nofinish'] = 0; + $datarray['uid'] = local_channel(); + $datarray['account'] = get_account_id(); + $datarray['event_xchan'] = $channel['channel_hash']; + $datarray['allow_cid'] = $str_contact_allow; + $datarray['allow_gid'] = $str_group_allow; + $datarray['deny_cid'] = $str_contact_deny; + $datarray['deny_gid'] = $str_group_deny; + $datarray['private'] = intval($private); + $datarray['id'] = $event_id; + $datarray['created'] = $created; + $datarray['edited'] = $edited; + $datarray['timezone'] = $tz; + + + if(intval($_REQUEST['preview'])) { + $html = format_event_html($datarray); + echo $html; + killme(); + } + + $event = event_store_event($datarray); + + if($post_tags) + $datarray['term'] = $post_tags; + + $item_id = event_store_item($datarray,$event); + + if($item_id) { + $r = q("select * from item where id = %d", + intval($item_id) + ); + if($r) { + xchan_query($r); + $sync_item = fetch_post_tags($r); + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($r[0]['resource_id']), + intval($channel['channel_id']) + ); + if($z) { + build_sync_packet($channel['channel_id'],array('event_item' => array(encode_item($sync_item[0],true)),'event' => $z)); + } + } + } + + \Zotlabs\Daemon\Master::Summon(array('Notifier','event',$item_id)); + + killme(); + + } + + + + function get() { + + if(argc() > 2 && argv(1) == 'ical') { + $event_id = argv(2); + + require_once('include/security.php'); + $sql_extra = permissions_sql(local_channel()); + + $r = q("select * from event where event_hash = '%s' $sql_extra limit 1", + dbesc($event_id) + ); + if($r) { + header('Content-type: text/calendar'); + header('content-disposition: attachment; filename="' . t('event') . '-' . $event_id . '.ics"' ); + echo ical_wrapper($r); + killme(); + } + else { + notice( t('Event not found.') . EOL ); + return; + } + } + + if(! local_channel()) { + notice( t('Permission denied.') . EOL); + return; + } + + if((argc() > 2) && (argv(1) === 'ignore') && intval(argv(2))) { + $r = q("update event set dismissed = 1 where id = %d and uid = %d", + intval(argv(2)), + intval(local_channel()) + ); + } + + if((argc() > 2) && (argv(1) === 'unignore') && intval(argv(2))) { + $r = q("update event set dismissed = 0 where id = %d and uid = %d", + intval(argv(2)), + intval(local_channel()) + ); + } + + $channel = \App::get_channel(); + + $mode = 'view'; + $export = false; + $ignored = ((x($_REQUEST,'ignored')) ? " and dismissed = " . intval($_REQUEST['ignored']) . " " : ''); + + if(argc() > 1) { + if(argc() > 2 && argv(1) === 'add') { + $mode = 'add'; + $item_id = intval(argv(2)); + } + if(argc() > 2 && argv(1) === 'drop') { + $mode = 'drop'; + $event_id = argv(2); + } + if(argc() <= 2 && argv(1) === 'export') { + $export = true; + } + if(argc() > 2 && intval(argv(1)) && intval(argv(2))) { + $mode = 'view'; + } + if(argc() <= 2) { + $mode = 'view'; + $event_id = argv(1); + } + } + + if($mode === 'add') { + event_addtocal($item_id,local_channel()); + killme(); + } + + if($mode == 'view') { + + /* edit/create form */ + if($event_id) { + $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($event_id), + intval(local_channel()) + ); + if(count($r)) + $orig_event = $r[0]; + } + + $channel = \App::get_channel(); + + if (argv(1) === 'json'){ + if (x($_GET,'start')) $start = $_GET['start']; + if (x($_GET,'end')) $finish = $_GET['end']; + } + + $start = datetime_convert('UTC','UTC',$start); + $finish = datetime_convert('UTC','UTC',$finish); + $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); + $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); + + if (x($_GET,'id')){ + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + from event left join item on item.resource_id = event.event_hash + where item.resource_type = 'event' and event.uid = %d and event.id = %d limit 1", + intval(local_channel()), + intval($_GET['id']) + ); + } + elseif($export) { + $r = q("SELECT event.*, item.id as item_id + from event left join item on item.resource_id = event.event_hash + where event.uid = %d and event.dtstart > '%s' and event.dtend > event.dtstart", + intval(local_channel()), + dbesc(NULL_DATE) + ); + } + else { + // fixed an issue with "nofinish" events not showing up in the calendar. + // There's still an issue if the finish date crosses the end of month. + // Noting this for now - it will need to be fixed here and in Friendica. + // Ultimately the finish date shouldn't be involved in the query. + + $r = q("SELECT event.*, item.plink, item.item_flags, item.author_xchan, item.owner_xchan, item.id as item_id + from event left join item on event.event_hash = item.resource_id + where item.resource_type = 'event' and event.uid = %d and event.uid = item.uid $ignored + AND (( event.adjust = 0 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' ) + OR ( event.adjust = 1 AND ( event.dtend >= '%s' or event.nofinish = 1 ) AND event.dtstart <= '%s' )) ", + intval(local_channel()), + dbesc($start), + dbesc($finish), + dbesc($adjust_start), + dbesc($adjust_finish) + ); + } + + if($r && ! $export) { + xchan_query($r); + $r = fetch_post_tags($r,true); + $r = sort_by_date($r); + } + + $events = []; + + if($r) { + + foreach($r as $rr) { + + $tz = get_iconfig($rr, 'event', 'timezone'); + + if(! $tz) + $tz = 'UTC'; + + $start = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtstart'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtstart'], 'c')); + if ($rr['nofinish']){ + $end = null; + } else { + $end = (($rr['adjust']) ? datetime_convert($tz, date_default_timezone_get(), $rr['dtend'], 'c') : datetime_convert('UTC', 'UTC', $rr['dtend'], 'c')); + } + + $catsenabled = feature_enabled(local_channel(),'categories'); + $categories = ''; + if($catsenabled){ + if($rr['term']) { + $cats = get_terms_oftype($rr['term'], TERM_CATEGORY); + foreach ($cats as $cat) { + if(strlen($categories)) + $categories .= ', '; + $categories .= $cat['term']; + } + } + } + + $edit = ((local_channel() && $rr['author_xchan'] == get_observer_hash()) ? array(z_root().'/events/'.$rr['event_hash'].'?expandform=1',t('Edit event'),'','') : false); + + $drop = array(z_root().'/events/drop/'.$rr['event_hash'],t('Delete event'),'',''); + + $events[] = array( + 'calendar_id' => 'channel_calendar', + 'rw' => true, + 'id'=>$rr['id'], + 'uri' => $rr['event_hash'], + 'timezone' => $tz, + 'start'=> $start, + 'end' => $end, + 'drop' => $drop, + 'allDay' => (($rr['adjust']) ? 0 : 1), + 'title' => htmlentities($rr['summary'], ENT_COMPAT, 'UTF-8', false), + 'editable' => $edit ? true : false, + 'item' => $rr, + 'plink' => [$rr['plink'], t('Link to source')], + 'description' => htmlentities($rr['description'], ENT_COMPAT, 'UTF-8', false), + 'location' => htmlentities($rr['location'], ENT_COMPAT, 'UTF-8', false), + 'allow_cid' => expand_acl($rr['allow_cid']), + 'allow_gid' => expand_acl($rr['allow_gid']), + 'deny_cid' => expand_acl($rr['deny_cid']), + 'deny_gid' => expand_acl($rr['deny_gid']), + 'categories' => $categories + ); + } + } + + if($export) { + header('Content-type: text/calendar'); + header('content-disposition: attachment; filename="' . t('calendar') . '-' . $channel['channel_address'] . '.ics"' ); + echo ical_wrapper($r); + killme(); + } + + if (\App::$argv[1] === 'json'){ + json_return_and_die($events); + } + } + + + if($mode === 'drop' && $event_id) { + $r = q("SELECT * FROM event WHERE event_hash = '%s' AND uid = %d LIMIT 1", + dbesc($event_id), + intval(local_channel()) + ); + + $sync_event = $r[0]; + + if($r) { + $r = q("delete from event where event_hash = '%s' and uid = %d", + dbesc($event_id), + intval(local_channel()) + ); + if($r) { + $r = q("update item set resource_type = '', resource_id = '' where resource_type = 'event' and resource_id = '%s' and uid = %d", + dbesc($event_id), + intval(local_channel()) + ); + $sync_event['event_deleted'] = 1; + build_sync_packet(0,array('event' => array($sync_event))); + killme(); + } + notice( t('Failed to remove event' ) . EOL); + killme(); + } + } + + } + +} diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index b67c00cdc..d97014f9c 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -68,7 +68,10 @@ class Cover_photo extends \Zotlabs\Web\Controller { if($sync) build_sync_packet($channel['channel_id'],array('file' => array($sync))); } - + + // Update directory in background + \Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id'])); + goaway(z_root() . '/cover_photo'); } @@ -129,7 +132,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { if(file_exists($tmp_name)) { $base_image = $r[0]; $gis = getimagesize($tmp_name); -logger('gis: ' . print_r($gis,true)); + logger('gis: ' . print_r($gis,true), LOGGER_DEBUG); $base_image['width'] = $gis[0]; $base_image['height'] = $gis[1]; $base_image['content'] = @file_get_contents($tmp_name); @@ -190,25 +193,18 @@ logger('gis: ' . print_r($gis,true)); 'filename' => $base_image['filename'], 'album' => t('Cover Photos'), 'os_path' => $base_image['os_path'], - 'display_path' => $base_image['display_path'] + 'display_path' => $base_image['display_path'], + 'photo_usage' => PHOTO_COVER ]; - - $p['imgscale'] = 7; - $p['photo_usage'] = PHOTO_COVER; - - $r1 = $im->save($p); + + $r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200); $im->doScaleImage(850,310); - $p['imgscale'] = 8; - - $r2 = $im->save($p); - + $r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850); $im->doScaleImage(425,160); - $p['imgscale'] = 9; - - $r3 = $im->save($p); - + $r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425); + if($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice( t('Image resize failed.') . EOL ); @@ -216,6 +212,17 @@ logger('gis: ' . print_r($gis,true)); dbesc($base_image['resource_id']), local_channel() ); + + $x = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1 AND imgscale >= 7", + dbesc($base_image['resource_id']), + local_channel() + ); + if($x) { + foreach($x as $xx) { + @unlink(dbunescbin($xx['content'])); + } + } + return; } @@ -224,7 +231,9 @@ logger('gis: ' . print_r($gis,true)); $sync = attach_export_data($channel,$base_image['resource_id']); if($sync) build_sync_packet($channel['channel_id'],array('file' => array($sync))); - + + // Update directory in background + \Zotlabs\Daemon\Master::Summon(array('Directory',$channel['channel_id'])); } else notice( t('Unable to process image') . EOL); diff --git a/Zotlabs/Module/Directory.php b/Zotlabs/Module/Directory.php index 5448a4816..8f5db6635 100644 --- a/Zotlabs/Module/Directory.php +++ b/Zotlabs/Module/Directory.php @@ -103,8 +103,14 @@ class Directory extends \Zotlabs\Web\Controller { $suggest = (local_channel() && x($_REQUEST,'suggest')) ? $_REQUEST['suggest'] : ''; if($suggest) { - - $r = suggestion_query(local_channel(),get_observer_hash()); + + // the directory options have no effect in suggestion mode + + $globaldir = 1; + $safe_mode = 1; + $type = 0; + + $r = suggestion_query(local_channel(),get_observer_hash(),0,60); if(! $r) { notice( t('No default suggestions were found.') . EOL); @@ -212,12 +218,17 @@ class Directory extends \Zotlabs\Web\Controller { if($j) { if($j['results']) { - + + $results = $j['results']; + if($suggest) { + $results = self::reorder_results($results,$addresses); + } + $entries = array(); $photo = 'thumb'; - foreach($j['results'] as $rr) { + foreach($results as $rr) { $profile_link = chanlink_url($rr['url']); @@ -438,5 +449,22 @@ class Directory extends \Zotlabs\Web\Controller { return $o; } - + static public function reorder_results($results,$suggests) { + + if(! $suggests) + return $results; + + $out = []; + foreach($suggests as $k => $v) { + foreach($results as $rv) { + if($k == $rv['address']) { + $out[intval($v)] = $rv; + break; + } + } + } + + return $out; + } + } diff --git a/Zotlabs/Module/Editpost.php b/Zotlabs/Module/Editpost.php index 1c9068e07..49b2892e8 100644 --- a/Zotlabs/Module/Editpost.php +++ b/Zotlabs/Module/Editpost.php @@ -45,7 +45,8 @@ class Editpost extends \Zotlabs\Web\Controller { } if($itm[0]['resource_type'] === 'event' && $itm[0]['resource_id']) { - goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1'); + goaway(z_root() . '/cdav/calendar/' . $itm[0]['resource_id']); + //goaway(z_root() . '/events/' . $itm[0]['resource_id'] . '?expandform=1'); } $owner_uid = $itm[0]['uid']; diff --git a/Zotlabs/Module/Embedphotos.php b/Zotlabs/Module/Embedphotos.php index 2df14c239..6a88513dc 100644 --- a/Zotlabs/Module/Embedphotos.php +++ b/Zotlabs/Module/Embedphotos.php @@ -41,24 +41,44 @@ class Embedphotos extends \Zotlabs\Web\Controller { json_return_and_die(array('errormsg' => 'Error retrieving link ' . $href, 'status' => false)); } $resource_id = array_pop(explode('/', $href)); - $r = q("SELECT obj from item where resource_type = 'photo' and resource_id = '%s' limit 1", - dbesc($resource_id) - ); - if (!$r) { - json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); - } - $obj = json_decode($r[0]['obj'], true); - if (x($obj, 'body')) { - $photolink = $obj['body']; - } elseif (x($obj, 'bbcode')) { - $photolink = $obj['bbcode']; - } else { - json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); - } - json_return_and_die(array('status' => true, 'photolink' => $photolink, 'resource_id' => $resource_id)); + $x = self::photolink($resource_id); + if($x) + json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id)); + json_return_and_die(array('errormsg' => 'Error retrieving resource ' . $resource_id, 'status' => false)); } } + + protected static function photolink($resource) { + $channel = \App::get_channel(); + $output = EMPTY_STR; + if($channel) { + $resolution = ((feature_enabled($channel['channel_id'],'large_photos')) ? 1 : 2); + $r = q("select mimetype, height, width from photo where resource_id = '%s' and $resolution = %d and uid = %d limit 1", + dbesc($resource), + intval($resolution), + intval($channel['channel_id']) + ); + if(! $r) + return $output; + + if($r[0]['mimetype'] === 'image/jpeg') + $ext = '.jpg'; + elseif($r[0]['mimetype'] === 'image/png') + $ext = '.png'; + elseif($r[0]['mimetype'] === 'image/gif') + $ext = '.gif'; + else + $ext = EMPTY_STR; + + $output = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $resource . ']' . + '[zmg=' . $r[0]['width'] . 'x' . $r[0]['height'] . ']' . z_root() . '/photo/' . $resource . '-' . $resolution . $ext . '[/zmg][/zrl]'; + + return $output; + } + } + + /** * @brief Get photos from an album. * diff --git a/Zotlabs/Module/Getfile.php b/Zotlabs/Module/Getfile.php index abc9f50d9..583cf38f0 100644 --- a/Zotlabs/Module/Getfile.php +++ b/Zotlabs/Module/Getfile.php @@ -35,7 +35,6 @@ class Getfile extends \Zotlabs\Web\Controller { $sig = $_POST['signature']; $resource = $_POST['resource']; $revision = intval($_POST['revision']); - $resolution = (-1); if(! $hash) killme(); @@ -81,9 +80,14 @@ class Getfile extends \Zotlabs\Web\Controller { killme(); } - if(substr($resource,-2,1) == '-') { + if(isset($_POST['resolution'])) + $resolution = intval($_POST['resolution']); + elseif(substr($resource,-2,1) == '-') { $resolution = intval(substr($resource,-1,1)); $resource = substr($resource,0,-2); + } + else { + $resolution = (-1); } $slop = intval(get_pconfig($channel['channel_id'],'system','getfile_time_slop')); @@ -106,9 +110,10 @@ class Getfile extends \Zotlabs\Web\Controller { } if($resolution > 0) { - $r = q("select * from photo where resource_id = '%s' and uid = %d limit 1", + $r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1", dbesc($resource), - intval($channel['channel_id']) + intval($channel['channel_id']), + $resolution ); if($r) { header('Content-type: ' . $r[0]['mimetype']); diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index 3d1f503b6..052d51d43 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -491,7 +491,7 @@ class Like extends \Zotlabs\Web\Controller { $arr['item_flags'] = $item_flags; $arr['item_wall'] = $item_wall; - $arr['parent_mid'] = (($extended_like) ? $mid : $item['mid']); + $arr['parent_mid'] = (($extended_like) ? $arr['mid'] : $item['mid']); $arr['owner_xchan'] = (($extended_like) ? $ch[0]['xchan_hash'] : $thread_owner['xchan_hash']); $arr['author_xchan'] = $observer['xchan_hash']; @@ -546,7 +546,7 @@ class Like extends \Zotlabs\Web\Controller { dbesc($observer['xchan_hash']), dbesc($ch[0]['channel_hash']), intval($post_id), - dbesc($mid), + dbesc($arr['mid']), dbesc($activity), dbesc(($tgttype)? $tgttype : $objtype), dbesc($obj_id), @@ -555,7 +555,7 @@ class Like extends \Zotlabs\Web\Controller { $r = q("select * from likes where liker = '%s' and likee = '%s' and i_mid = '%s' and verb = '%s' and target_type = '%s' and target_id = '%s' ", dbesc($observer['xchan_hash']), dbesc($ch[0]['channel_hash']), - dbesc($mid), + dbesc($arr['mid']), dbesc($activity), dbesc(($tgttype)? $tgttype : $objtype), dbesc($obj_id) diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php index 32b4c0281..b9f90deec 100644 --- a/Zotlabs/Module/Linkinfo.php +++ b/Zotlabs/Module/Linkinfo.php @@ -69,6 +69,14 @@ class Linkinfo extends \Zotlabs\Web\Controller { killme(); } if(stripos($type,'video/') !== false) { + $thumb = self::get_video_poster($url); + if($thumb) { + if ($zrl) + echo $br . '[zvideo poster=\'' . $thumb . '\']' . $url . '[/zvideo]' . $br; + else + echo $br . '[video poster=\'' . $thumb . '\']' . $url . '[/video]' . $br; + killme(); + } if($zrl) echo $br . '[zvideo]' . $url . '[/zvideo]' . $br; else @@ -216,7 +224,42 @@ class Linkinfo extends \Zotlabs\Web\Controller { return($complete); } - + + public static function get_video_poster($url) { + + if(strpos($url,z_root() . '/cloud/') === false) { + return EMPTY_STR; + } + $m = parse_url($url,PHP_URL_PATH); + if($m) { + // strip leading '/cloud/' + $m = substr($m,7); + } + $nick = substr($m,0,strpos($m,'/')); + $p = substr($m,strpos($m,'/')+1); + + // get the channel to check permissions + + $u = channelx_by_nick($nick); + + if($u && $p) { + + $sql_extra = permissions_sql(intval($u['channel_id'])); + + $r = q("select hash, content from attach where display_path = '%s' and uid = %d and os_storage = 1 $sql_extra limit 1", + dbesc($p), + intval($u['channel_id']) + ); + if($r) { + $path = dbunescbin($r[0]['content']); + if($path && @file_exists($path . '.thumb')) { + return z_root() . '/poster/' . $nick . '/' . $r[0]['hash']; + } + } + } + return EMPTY_STR; + } + public static function parseurl_getsiteinfo($url) { $siteinfo = array(); diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 6912322aa..0dc6d0194 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -40,7 +40,7 @@ class Photo extends \Zotlabs\Web\Controller { call_hooks('cache_mode_hook', $cache_mode); $observer_xchan = get_observer_hash(); - $ismodified = $_SERVER['HTTP_IF_MODIFIED_SINCE']; + $cachecontrol = ''; if(isset($type)) { @@ -68,8 +68,6 @@ class Photo extends \Zotlabs\Web\Controller { } } - $modified = filemtime($default); - $default = z_root() . '/' . $default; $uid = $person; $data = ''; @@ -83,7 +81,7 @@ class Photo extends \Zotlabs\Web\Controller { $modified = strtotime($r[0]['edited'] . "Z"); $mimetype = $r[0]['mimetype']; if(intval($r[0]['os_storage'])) - $data = file_get_contents($data); + $data = file_get_contents(dbunescbin($r[0]['content'])); else $data = dbunescbin($r[0]['content']); } @@ -97,13 +95,17 @@ class Photo extends \Zotlabs\Web\Controller { $default = $d['default']; $data = $d['data']; $mimetype = $d['mimetype']; + $modified = 0; } if(! $data) { - $x = z_fetch_url($default,true,0,[ 'novalidate' => true ]); + $x = z_fetch_url(z_root() . '/' . $default, true, 0, [ 'novalidate' => true ]); $data = ($x['success'] ? $x['body'] : EMPTY_STR); $mimetype = 'image/png'; + $modified = filemtime($default); } + + $cachecontrol = ', must-revalidate'; } else { @@ -160,18 +162,19 @@ class Photo extends \Zotlabs\Web\Controller { $allowed = (-1); if($u === PHOTO_CACHE) { // Validate cache - $cache = array( - 'resid' => $photo, - 'status' => false - ); - if($cache_mode['on']) + if($cache_mode['on']) { + $cache = array( + 'resid' => $photo, + 'status' => false + ); call_hooks('cache_url_hook', $cache); - if(! $cache['status']) { - $url = htmlspecialchars_decode($r[0]['display_path']); - if(strpos(z_root(),'https:') !== false && strpos($url,'https:') === false) - $url = z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($url); - header("Location: " . $url); - killme(); + if(! $cache['status']) { + $url = htmlspecialchars_decode($r[0]['display_path']); + // SSLify if needed + if(strpos(z_root(),'https:') !== false && strpos($url,'https:') === false) + $url = z_root() . '/sslify/' . $filename . '?f=&url=' . urlencode($url); + goaway($url); + } } } } @@ -216,38 +219,23 @@ class Photo extends \Zotlabs\Web\Controller { http_status_exit(404,'not found'); } + if(! $data) + killme(); + + $etag = md5($data . $modified); + + if($modified == 0) + $modified = time(); + header_remove('Pragma'); - if($ismodified === gmdate("D, d M Y H:i:s", $modified) . " GMT") { + if($_SERVER['HTTP_IF_NONE_MATCH'] === $etag || $_SERVER['HTTP_IF_MODIFIED_SINCE'] === gmdate("D, d M Y H:i:s", $modified) . " GMT") { header_remove('Expires'); header_remove('Cache-Control'); header_remove('Set-Cookie'); http_status_exit(304,'not modified'); - } - - if(! isset($data)) { - if(isset($resolution)) { - switch($resolution) { - case 4: - $default = get_default_profile_photo(); - break; - case 5: - $default = get_default_profile_photo(80); - break; - case 6: - $default = get_default_profile_photo(48); - break; - default: - killme(); - // NOTREACHED - break; - } - $x = z_fetch_url(z_root() . '/' . $default,true,0,[ 'novalidate' => true ]); - $data = ($x['success'] ? $x['body'] : EMPTY_STR); - $mimetype = 'image/png'; - } } - + if(isset($res) && intval($res) && $res < 500) { $ph = photo_factory($data, $mimetype); if($ph->is_valid()) { @@ -284,12 +272,13 @@ class Photo extends \Zotlabs\Web\Controller { $maxage = $expires - time(); header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT"); - header("Cache-Control: max-age=" . $maxage); + header("Cache-Control: max-age=" . $maxage . $cachecontrol); } header("Content-type: " . $mimetype); header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT"); + header("ETag: " . $etag); header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data))); // If it's a file resource, stream it. diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php index 3a6d77f00..13ec64ab9 100644 --- a/Zotlabs/Module/Photos.php +++ b/Zotlabs/Module/Photos.php @@ -239,95 +239,53 @@ class Photos extends \Zotlabs\Web\Controller { intval($page_owner_uid) ); if(count($r)) { - $d = (($r[0]['os_storage']) ? @file_get_contents(dbunescbin($r[0]['content'])) : dbunescbin($r[0]['content'])); - $ph = photo_factory($d, $r[0]['mimetype']); + + $ph = photo_factory(@file_get_contents(dbunescbin($r[0]['content'])), $r[0]['mimetype']); if($ph->is_valid()) { $rotate_deg = ( (intval($_POST['rotate']) == 1) ? 270 : 90 ); $ph->rotate($rotate_deg); - - $width = $ph->getWidth(); - $height = $ph->getHeight(); - - if(intval($r[0]['os_storage'])) { - @file_put_contents($r[0]['content'],$ph->imageString()); - $data = $r[0]['content']; - $fsize = @filesize($r[0]['content']); - q("update attach set filesize = %d where hash = '%s' and uid = %d", - intval($fsize), - dbesc($resource_id), - intval($page_owner_uid) - ); - } - else { - $data = $ph->imageString(); - $fsize = strlen($data); - } - - $x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 0", - dbesc(datetime_convert()), - dbescbin($data), - intval($fsize), - intval($height), - intval($width), + + $edited = datetime_convert(); + + q("update attach set filesize = %d, edited = '%s' where hash = '%s' and uid = %d", + strlen($ph->imageString()), + dbescdate($edited), dbesc($resource_id), intval($page_owner_uid) ); - + + $ph->saveImage(dbunescbin($r[0]['content'])); + + $arr = [ + 'aid' => get_account_id(), + 'uid' => intval($page_owner_uid), + 'resource_id' => dbesc($resource_id), + 'filename' => $r[0]['filename'], + 'imgscale' => 0, + 'album' => $r[0]['album'], + 'os_path' => $r[0]['os_path'], + 'os_storage' => 1, + 'os_syspath' => dbunescbin($r[0]['content']), + 'display_path' => $r[0]['display_path'], + 'photo_usage' => PHOTO_NORMAL, + 'edited' => dbescdate($edited) + ]; + + $ph->save($arr); + + unset($arr['os_syspath']); + if($width > 1024 || $height > 1024) $ph->scaleImage(1024); - - $width = $ph->getWidth(); - $height = $ph->getHeight(); - $data = $ph->imageString(); - $fsize = strlen($data); - - $x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 1", - dbesc(datetime_convert()), - dbescbin($data), - intval($fsize), - intval($height), - intval($width), - dbesc($resource_id), - intval($page_owner_uid) - ); - - + $ph->storeThumbnail($arr, PHOTO_RES_1024); + if($width > 640 || $height > 640) $ph->scaleImage(640); - - $width = $ph->getWidth(); - $height = $ph->getHeight(); - $data = $ph->imageString(); - $fsize = strlen($data); - - $x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 2", - dbesc(datetime_convert()), - dbescbin($data), - intval($fsize), - intval($height), - intval($width), - dbesc($resource_id), - intval($page_owner_uid) - ); - - + $ph->storeThumbnail($arr, PHOTO_RES_640); + if($width > 320 || $height > 320) $ph->scaleImage(320); - - $width = $ph->getWidth(); - $height = $ph->getHeight(); - $data = $ph->imageString(); - $fsize = strlen($data); - - $x = q("update photo set edited = '%s', content = '%s', filesize = %d, height = %d, width = %d where resource_id = '%s' and uid = %d and imgscale = 3", - dbesc(datetime_convert()), - dbescbin($data), - intval($fsize), - intval($height), - intval($width), - dbesc($resource_id), - intval($page_owner_uid) - ); + $ph->storeThumbnail($arr, PHOTO_RES_320); } } } diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index a367b1062..3dabe0f7b 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -447,7 +447,7 @@ class Ping extends \Zotlabs\Web\Controller { $when = day_translate(datetime_convert('UTC', (($rr['adjust']) ? date_default_timezone_get() : 'UTC'), $rr['dtstart'], $bd_format)) . (($today) ? ' ' . t('[today]') : ''); $result[] = array( - 'notify_link' => z_root() . '/events', /// @FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'], + 'notify_link' => z_root() . '/cdav/calendar/' . $rr['event_hash'], 'name' => $rr['xchan_name'], 'addr' => $rr['xchan_addr'], 'url' => $rr['xchan_url'], diff --git a/Zotlabs/Module/Poster.php b/Zotlabs/Module/Poster.php new file mode 100644 index 000000000..10317ee61 --- /dev/null +++ b/Zotlabs/Module/Poster.php @@ -0,0 +1,37 @@ + array($sync))); + } + + $_SESSION['reload_avatar'] = true; + + goaway(z_root() . '/profiles'); + } if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) { // logger('crop: ' . print_r($_POST,true)); - - // phase 2 - we have finished cropping if(argc() != 2) { @@ -119,39 +144,48 @@ class Profile_photo extends \Zotlabs\Web\Controller { 'filename' => $base_image['filename'], 'album' => t('Profile Photos'), 'os_path' => $base_image['os_path'], - 'display_path' => $base_image['display_path'] + 'display_path' => $base_image['display_path'], + 'photo_usage' => PHOTO_PROFILE, + 'edited' => dbescdate($base_image['edited']) ]; - $p['imgscale'] = PHOTO_RES_PROFILE_300; $p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL); - $r1 = $im->save($p); + $r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300); $im->scaleImage(80); - $p['imgscale'] = PHOTO_RES_PROFILE_80; - - $r2 = $im->save($p); + $r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80); $im->scaleImage(48); - $p['imgscale'] = PHOTO_RES_PROFILE_48; - - $r3 = $im->save($p); - + $r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48); + if($r1 === false || $r2 === false || $r3 === false) { // if one failed, delete them all so we can start over. notice( t('Image resize failed.') . EOL ); - $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ", + $x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d )", dbesc($base_image['resource_id']), local_channel(), intval(PHOTO_RES_PROFILE_300), intval(PHOTO_RES_PROFILE_80), intval(PHOTO_RES_PROFILE_48) ); + + $x = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1 AND imgscale IN ( %d, %d, %d )", + dbesc($base_image['resource_id']), + local_channel(), + intval(PHOTO_RES_PROFILE_300), + intval(PHOTO_RES_PROFILE_80), + intval(PHOTO_RES_PROFILE_48) + ); + if($x) { + foreach($x as $xx) { + @unlink(dbunescbin($xx['content'])); + } + } + return; } - $channel = \App::get_channel(); - // If setting for the default profile, unset the profile photo flag from any other photos I own if($is_default_profile) { @@ -198,7 +232,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { $r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s' where xchan_hash = '%s'", dbesc($im->getType()), - dbesc(datetime_convert()), + dbescdate($base_image['edited']), dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']), dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']), dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']), @@ -245,7 +279,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { else { require_once('include/attach.php'); - $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash)); + $res = attach_store(\App::get_channel(), get_observer_hash(), '', array('album' => t('Profile Photos'), 'hash' => $hash, 'nosync' => true)); logger('attach_store: ' . print_r($res,true)); } @@ -353,20 +387,23 @@ class Profile_photo extends \Zotlabs\Web\Controller { if($havescale) { // unset any existing profile photos - $r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", + $x = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d", intval(PHOTO_NORMAL), intval(PHOTO_PROFILE), - intval(local_channel())); - - $r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'", + intval(local_channel()) + ); + + $edited = datetime_convert(); + + $x = q("UPDATE photo SET photo_usage = %d, edited = '%s' WHERE uid = %d AND resource_id = '%s' AND imgscale > 0", intval(PHOTO_PROFILE), + dbescdate($edited), intval(local_channel()), dbesc($resource_id) - ); + ); - $r = q("UPDATE xchan set xchan_photo_date = '%s' - where xchan_hash = '%s'", - dbesc(datetime_convert()), + $x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'", + dbescdate($edited), dbesc($channel['xchan_hash']) ); @@ -376,8 +413,10 @@ class Profile_photo extends \Zotlabs\Web\Controller { if($sync) build_sync_packet($channel['channel_id'],array('file' => array($sync))); + $_SESSION['reload_avatar'] = true; \Zotlabs\Daemon\Master::Summon(array('Directory',local_channel())); + goaway(z_root() . '/profiles'); } @@ -457,6 +496,7 @@ class Profile_photo extends \Zotlabs\Web\Controller { '$lbl_profiles' => t('Select a profile:'), '$title' => (($importing) ? t('Use Photo for Profile') : t('Change Profile Photo')), '$submit' => (($importing) ? t('Use') : t('Upload')), + '$remove' => t('Remove'), '$profiles' => $profiles, '$single' => ((count($profiles) == 1) ? true : false), '$profile0' => $profiles[0], diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index 3920301f5..f80b04a3f 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -59,6 +59,14 @@ class React extends \Zotlabs\Web\Controller { $n['body'] = "\n\n[zmg=32x32]" . z_root() . '/images/emoji/' . $emoji . '.png[/zmg]' . "\n\n"; $n['author_xchan'] = $channel['channel_hash']; + $n['tgt_type'] = 'Image'; + $n['target'] = [ + 'type' => 'Image', + 'name' => $emoji, + 'url' => z_root() . '/images/emoji/' . $emoji . '.png' + ]; + + $x = item_store($n); retain_item($postid); diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php index f9d81be0c..bc813f8e1 100644 --- a/Zotlabs/Module/Register.php +++ b/Zotlabs/Module/Register.php @@ -1,10 +1,11 @@ %s - INTERVAL %s", @@ -269,7 +272,8 @@ class Register extends \Zotlabs\Web\Controller { require_once('include/bbcode.php'); $o = replace_macros(get_markup_template('register.tpl'), array( - + + '$form_security_token' => get_form_security_token("register"), '$title' => t('Registration'), '$reg_is' => $registration_is, '$registertext' => bbcode(get_config('system','register_text')), diff --git a/Zotlabs/Module/Search.php b/Zotlabs/Module/Search.php index 838f9d6b9..214ece9a3 100644 --- a/Zotlabs/Module/Search.php +++ b/Zotlabs/Module/Search.php @@ -38,8 +38,8 @@ class Search extends \Zotlabs\Web\Controller { $observer_hash = (($observer) ? $observer['xchan_hash'] : ''); $o = '' . "\r\n"; - - $o = '
' . "\r\n"; + + $o .= '
' . "\r\n"; $o .= '

' . t('Search') . '

'; diff --git a/Zotlabs/Module/Settings/Calendar.php b/Zotlabs/Module/Settings/Calendar.php index a27bf0fa5..0298b412e 100644 --- a/Zotlabs/Module/Settings/Calendar.php +++ b/Zotlabs/Module/Settings/Calendar.php @@ -36,7 +36,7 @@ class Calendar { '$rpath' => $rpath, '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), - '$title' => t('CalDAV Settings'), + '$title' => t('Calendar Settings'), '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); diff --git a/Zotlabs/Module/Wall_attach.php b/Zotlabs/Module/Wall_attach.php index 2250e6e44..0ede3ad90 100644 --- a/Zotlabs/Module/Wall_attach.php +++ b/Zotlabs/Module/Wall_attach.php @@ -96,9 +96,26 @@ class Wall_attach extends \Zotlabs\Web\Controller { $s = "\n\n" . $r['body'] . "\n\n"; } else { - $s = "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n"; + if(strpos($r['data']['filetype'],'video') === 0) { + // give a wee bit of time for the background thumbnail processor to do its thing + // or else we'll never see a video poster + sleep(3); + $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']; + $thumb = Linkinfo::get_video_poster($url); + if($thumb) { + $s = "\n\n" . '[zvideo poster=\'' . $thumb . '\']' . $url . '[/zvideo]' . "\n\n"; + } + else { + $s = "\n\n" . '[zvideo]' . $url . '[/zvideo]' . "\n\n"; + } + } + if(strpos($r['data']['filetype'],'audio') === 0) { + $url = z_root() . '/cloud/' . $channel['channel_address'] . '/' . $r['data']['display_path']; + echo "\n\n" . '[zaudio]' . $url . '[/zaudio]' . "\n\n"; + } + + $s .= "\n\n" . '[attachment]' . $r['data']['hash'] . ',' . $r['data']['revision'] . '[/attachment]' . "\n"; } - $sync = attach_export_data($channel,$r['data']['hash']); if($sync) { diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 502f96a62..169dc6de1 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -293,9 +293,9 @@ class Wiki extends Controller { } //$wikiheaderName = urldecode($wikiUrlName); - $wikiheaderName = NativeWiki::name_decode($wikiUrlName); + $wikiheaderName = escape_tags(NativeWiki::name_decode($wikiUrlName)); //$wikiheaderPage = urldecode($pageUrlName); - $wikiheaderPage = NativeWiki::name_decode($pageUrlName); + $wikiheaderPage = escape_tags(NativeWiki::name_decode($pageUrlName)); $renamePage = (($wikiheaderPage === 'Home') ? '' : t('Rename page')); $sharePage = t('Share'); @@ -373,13 +373,13 @@ class Wiki extends Controller { $placeholder = t('Short description of your changes (optional)'); - $zrl = urlencode( z_root() . '/wiki/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName) . '/' . NativeWiki::name_encode($pageUrlName) ); + $zrl = z_root() . '/wiki/' . argv(1) . '/' . NativeWiki::name_encode($wikiUrlName) . '/' . NativeWiki::name_encode($pageUrlName); $o .= replace_macros(get_markup_template('wiki.tpl'),array( '$wikiheaderName' => $wikiheaderName, '$wikiheaderPage' => $wikiheaderPage, '$renamePage' => $renamePage, '$sharePage' => $sharePage, - '$shareLink' => '#^[zrl=' . $zrl . ']' . '[ ' . $owner['channel_name'] . ' ] ' . $wikiheaderName . ' - ' . $wikiheaderPage . '[/zrl]', + '$shareLink' => urlencode('#^[zrl=' . $zrl . ']' . '[ ' . $owner['channel_name'] . ' ] ' . $wikiheaderName . ' - ' . $wikiheaderPage . '[/zrl]'), '$showPageControls' => $showPageControls, '$editOrSourceLabel' => (($showPageControls) ? t('Edit') : t('Source')), '$tools_label' => 'Page Tools', diff --git a/Zotlabs/Photo/PhotoDriver.php b/Zotlabs/Photo/PhotoDriver.php index c47a7c3b2..146ef0ae4 100644 --- a/Zotlabs/Photo/PhotoDriver.php +++ b/Zotlabs/Photo/PhotoDriver.php @@ -448,6 +448,7 @@ abstract class PhotoDriver { $p['width'] = (($arr['width']) ? $arr['width'] : $this->getWidth()); $p['height'] = (($arr['height']) ? $arr['height'] : $this->getHeight()); $p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system', 'photo_cache_time', 86400))); + $p['profile'] = ((array_key_exists('profile', $arr)) ? intval($arr['profile']) : 0); if(! intval($p['imgscale'])) logger('save: ' . print_r($arr, true), LOGGER_DATA); @@ -481,18 +482,49 @@ abstract class PhotoDriver { allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', - expires = '%s' + expires = '%s', + profile = %d where id = %d", - intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($x[0]['id'])); + intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile']), intval($x[0]['id'])); } else { $p['created'] = (($arr['created']) ? $arr['created'] : $p['edited']); $r = q("INSERT INTO photo - ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires ) - VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires'])); + ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires, profile ) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", intval($p['aid']), intval($p['uid']), dbesc($p['xchan']), dbesc($p['resource_id']), dbescdate($p['created']), dbescdate($p['edited']), dbesc(basename($p['filename'])), dbesc($p['mimetype']), dbesc($p['album']), intval($p['height']), intval($p['width']), (intval($p['os_storage']) ? dbescbin($p['os_syspath']) : dbescbin($this->imageString())), intval($p['os_storage']), (intval($p['os_storage']) ? @filesize($p['os_syspath']) : strlen($this->imageString())), intval($p['imgscale']), intval($p['photo_usage']), dbesc($p['title']), dbesc($p['description']), dbesc($p['os_path']), dbesc($p['display_path']), dbesc($p['allow_cid']), dbesc($p['allow_gid']), dbesc($p['deny_cid']), dbesc($p['deny_gid']), dbescdate($p['expires']), intval($p['profile'])); } logger('Photo save imgscale ' . $p['imgscale'] . ' returned ' . intval($r)); return $r; } + + /** + * @brief Stores thumbnail to database or filesystem. + * + * @param array $arr + * @param scale int + * @return boolean|array + */ + public function storeThumbnail($arr, $scale = 0) { + + $arr['imgscale'] = $scale; + + if(boolval(get_config('system','filesystem_storage_thumbnails', 0)) && $scale > 0) { + $channel = channelx_by_n($arr['uid']); + $arr['os_storage'] = 1; + $arr['os_syspath'] = 'store/' . $channel['channel_address'] . '/' . $arr['os_path'] . '-' . $scale; + if(! $this->saveImage($arr['os_syspath'])) + return false; + } + else + $arr['os_storage'] = 0; + + if(! $this->save($arr)) { + if(array_key_exists('os_syspath', $arr)) + @unlink($arr['os_syspath']); + return false; + } + + return true; + } } diff --git a/Zotlabs/Render/SmartyInterface.php b/Zotlabs/Render/SmartyInterface.php index 9c9a501c0..a40effecf 100755 --- a/Zotlabs/Render/SmartyInterface.php +++ b/Zotlabs/Render/SmartyInterface.php @@ -2,7 +2,10 @@ namespace Zotlabs\Render; -class SmartyInterface extends \Smarty { +use Smarty; +use App; + +class SmartyInterface extends Smarty { public $filename; @@ -16,26 +19,27 @@ class SmartyInterface extends \Smarty { // The order is thus very important here $template_dirs = array('theme' => "view/theme/$thname/tpl/"); - if( x(\App::$theme_info,"extends") ) + if ( x(App::$theme_info,"extends") ) { $template_dirs = $template_dirs + array('extends' => "view/theme/" . \App::$theme_info["extends"] . "/tpl/"); + } $template_dirs = $template_dirs + array('base' => 'view/tpl/'); $this->setTemplateDir($template_dirs); - $basecompiledir = \App::$config['system']['smarty3_folder']; + $basecompiledir = App::$config['system']['smarty3_folder']; $this->setCompileDir($basecompiledir.'/compiled/'); $this->setConfigDir($basecompiledir.'/config/'); $this->setCacheDir($basecompiledir.'/cache/'); - $this->left_delimiter = \App::get_template_ldelim('smarty3'); - $this->right_delimiter = \App::get_template_rdelim('smarty3'); + $this->left_delimiter = App::get_template_ldelim('smarty3'); + $this->right_delimiter = App::get_template_rdelim('smarty3'); // Don't report errors so verbosely $this->error_reporting = E_ALL & (~E_NOTICE); } function parsed($template = '') { - if($template) { + if ($template) { return $this->fetch('string:' . $template); } return $this->fetch('file:' . $this->filename); diff --git a/Zotlabs/Render/SmartyTemplate.php b/Zotlabs/Render/SmartyTemplate.php index f14d63064..61fb72f8a 100755 --- a/Zotlabs/Render/SmartyTemplate.php +++ b/Zotlabs/Render/SmartyTemplate.php @@ -2,28 +2,33 @@ namespace Zotlabs\Render; +use App; + + class SmartyTemplate implements TemplateEngine { static $name ="smarty3"; - public function __construct(){ + public function __construct() { // Cannot use get_config() here because it is called during installation when there is no DB. // FIXME: this may leak private information such as system pathnames. - $basecompiledir = ((array_key_exists('smarty3_folder',\App::$config['system'])) - ? \App::$config['system']['smarty3_folder'] : ''); - if (!$basecompiledir) $basecompiledir = str_replace('Zotlabs','',dirname(__dir__)) . "/" . TEMPLATE_BUILD_PATH; - if (!is_dir($basecompiledir)) { + $basecompiledir = ((array_key_exists('smarty3_folder', App::$config['system'])) + ? App::$config['system']['smarty3_folder'] : ''); + if (! $basecompiledir) { + $basecompiledir = str_replace('Zotlabs','',dirname(__dir__)) . "/" . TEMPLATE_BUILD_PATH; + } + if (! is_dir($basecompiledir)) { @os_mkdir(TEMPLATE_BUILD_PATH, STORAGE_DEFAULT_PERMISSIONS, true); - if (!is_dir($basecompiledir)) { + if (! is_dir($basecompiledir)) { echo "ERROR: folder $basecompiledir does not exist."; killme(); } } - if(!is_writable($basecompiledir)){ + if (! is_writable($basecompiledir)) { echo "ERROR: folder $basecompiledir must be writable by webserver."; killme(); } - \App::$config['system']['smarty3_folder'] = $basecompiledir; + App::$config['system']['smarty3_folder'] = $basecompiledir; } // TemplateEngine interface @@ -31,18 +36,18 @@ class SmartyTemplate implements TemplateEngine { public function replace_macros($s, $r) { $template = ''; - // these are available for use in all templates + // macro or macros available for use in all templates $r['$z_baseurl'] = z_root(); $r['$z_server_role'] = \Zotlabs\Lib\System::get_server_role(); $r['$z_techlevel'] = get_account_techlevel(); - if(gettype($s) === 'string') { + if (gettype($s) === 'string') { $template = $s; $s = new SmartyInterface(); } - foreach($r as $key=>$value) { - if($key[0] === '$') { + foreach ($r as $key=>$value) { + if ($key[0] === '$') { $key = substr($key, 1); } $s->assign($key, $value); @@ -50,32 +55,32 @@ class SmartyTemplate implements TemplateEngine { return $s->parsed($template); } - public function get_markup_template($file, $root=''){ + public function get_markup_template($file, $root = '') { $template_file = theme_include($file, $root); - if($template_file) { + if ($template_file) { $template = new SmartyInterface(); $template->filename = $template_file; return $template; } - return ""; + return EMPTY_STR; } - public function get_intltext_template($file, $root='') { + public function get_intltext_template($file, $root = '') { - $lang = \App::$language; - if ($root != '' && substr($root,-1) != '/' ) { - $root .= '/'; - } - foreach (Array( - $root."view/$lang/$file", - $root."view/en/$file", - '' - ) as $template_file) { - if (is_file($template_file)) { break; } - } - if ($template_file=='') {$template_file = theme_include($file,$root);} - if($template_file) { + $lang = App::$language; + if ($root != '' && substr($root,-1) != '/' ) { + $root .= '/'; + } + foreach ( [ $root . "view/$lang/$file", $root . "view/en/$file", '' ] as $template_file) { + if (is_file($template_file)) { + break; + } + } + if ($template_file == '') { + $template_file = theme_include($file,$root); + } + if ($template_file) { $template = new SmartyInterface(); $template->filename = $template_file; return $template; diff --git a/Zotlabs/Update/_1232.php b/Zotlabs/Update/_1232.php new file mode 100644 index 000000000..d1e3d75b5 --- /dev/null +++ b/Zotlabs/Update/_1232.php @@ -0,0 +1,47 @@ + $channel['channel_address'], + 'displayname' => $channel['channel_name'], + 'calendarid' => 'channel_calendar', + 'json_source' => '/channel_calendar/json', + 'color' => '#3a87ad', + 'editable' => true, + 'switch' => get_pconfig(local_channel(), 'cdav_calendar', 'channel_calendar') + ]; + $o .= replace_macros(get_markup_template('cdav_widget_calendar.tpl'), [ - '$my_calendars_label' => t('My Calendars'), + '$channel_calendars_label' => t('Channel Calendar'), + '$channel_calendars' => $channel_calendars, + '$my_calendars_label' => t('CalDAV Calendars'), '$my_calendars' => $my_calendars, - '$shared_calendars_label' => t('Shared Calendars'), + '$shared_calendars_label' => t('Shared CalDAV Calendars'), '$shared_calendars' => $shared_calendars, '$sharee_options' => $sharee_options, '$access_options' => $access_options, @@ -124,10 +136,11 @@ class Cdav { '$share' => t('Share'), '$edit_label' => t('Calendar name and color'), '$edit' => t('Edit'), - '$create_label' => t('Create new calendar'), + '$create_label' => t('Create new CalDAV calendar'), '$create' => t('Create'), '$create_placeholder' => t('Calendar Name'), '$tools_label' => t('Calendar Tools'), + '$tools_options_label' => [t('Channel Calendars'), t('CalDAV Calendars')], '$import_label' => t('Import calendar'), '$import_placeholder' => t('Select a calendar to import to'), '$upload' => t('Upload'), diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php index 37d9139ec..077949b4e 100644 --- a/Zotlabs/Widget/Notifications.php +++ b/Zotlabs/Widget/Notifications.php @@ -69,7 +69,7 @@ class Notifications { 'label' => t('New Events'), 'title' => t('New Events Notifications'), 'viewall' => [ - 'url' => 'events', + 'url' => 'cdav/calendar', 'label' => t('View events') ], 'markall' => [ diff --git a/app/caldav.apd b/app/calendar.apd similarity index 59% rename from app/caldav.apd rename to app/calendar.apd index 30b45b4bd..8de046e48 100644 --- a/app/caldav.apd +++ b/app/calendar.apd @@ -1,6 +1,6 @@ -version: 2 +version: 1 url: $baseurl/cdav/calendar, $baseurl/settings/calendar requires: local_channel -name: CalDAV +name: Calendar photo: icon:calendar -categories: Productivity, Personal +categories: Productivity, nav_featured_app diff --git a/app/events.apd b/app/events.apd deleted file mode 100644 index b69ee35ee..000000000 --- a/app/events.apd +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -url: $baseurl/events, $baseurl/settings/events -requires: local_channel -name: Events -photo: icon:calendar -categories: nav_featured_app, Productivity diff --git a/app/events.png b/app/events.png deleted file mode 100644 index a5670fd1e..000000000 Binary files a/app/events.png and /dev/null differ diff --git a/boot.php b/boot.php index 5e653e20f..5904cac3c 100755 --- a/boot.php +++ b/boot.php @@ -50,10 +50,10 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '4.0.3' ); +define ( 'STD_VERSION', '4.2' ); define ( 'ZOT_REVISION', '6.0a' ); -define ( 'DB_UPDATE_VERSION', 1231 ); +define ( 'DB_UPDATE_VERSION', 1234 ); define ( 'PROJECT_BASE', __DIR__ ); @@ -84,7 +84,8 @@ define ( 'DIRECTORY_FALLBACK_MASTER', 'https://zotadel.net'); $DIRECTORY_FALLBACK_SERVERS = array( 'https://zotadel.net', - 'https://zotsite.net' + 'https://zotsite.net', + 'https://hub.netzgemeinde.eu' ); @@ -467,7 +468,7 @@ define ( 'NAMESPACE_YMEDIA', 'http://search.yahoo.com/mrss/' ); define ( 'ACTIVITYSTREAMS_JSONLD_REV', 'https://www.w3.org/ns/activitystreams' ); -define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.3' ); +define ( 'ZOT_APSCHEMA_REV', '/apschema/v1.5' ); /** * activity stream defines */ diff --git a/composer.json b/composer.json index cb14083f0..b8fcd51b6 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "lukasreschke/id3parser": "^0.0.1", "smarty/smarty": "~3.1", "ramsey/uuid": "^3.8", - "twbs/bootstrap": "4.1.3", + "twbs/bootstrap": "^4.3.1", "blueimp/jquery-file-upload": "^9.25", "desandro/imagesloaded": "^4.1" }, diff --git a/composer.lock b/composer.lock index 2631b8dac..2520df134 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8da1fe9aabe6c20d116a21f63fff8ac2", + "content-hash": "f4dce457cd65f92a26d8197617f2f560", "packages": [ { "name": "blueimp/jquery-file-upload", - "version": "v9.28.0", + "version": "v9.30.0", "source": { "type": "git", "url": "https://github.com/vkhramtsov/jQuery-File-Upload.git", - "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d" + "reference": "1fceec556879403e5c1ae32a7c448aa12b8c3558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/ff5accfe2e5c4a522777faa980a90cf86a636d1d", - "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d", + "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/1fceec556879403e5c1ae32a7c448aa12b8c3558", + "reference": "1fceec556879403e5c1ae32a7c448aa12b8c3558", "shasum": "" }, "type": "library", @@ -59,7 +59,7 @@ "upload", "widget" ], - "time": "2018-11-13T05:41:39+00:00" + "time": "2019-04-22T09:21:57+00:00" }, { "name": "bshaffer/oauth2-server-php", @@ -861,16 +861,16 @@ }, { "name": "sabre/vobject", - "version": "4.1.6", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/sabre-io/vobject.git", - "reference": "122cacbdea2c6133ac04db86ec05854beef75adf" + "reference": "bd500019764e434ff65872d426f523e7882a0739" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/122cacbdea2c6133ac04db86ec05854beef75adf", - "reference": "122cacbdea2c6133ac04db86ec05854beef75adf", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/bd500019764e434ff65872d426f523e7882a0739", + "reference": "bd500019764e434ff65872d426f523e7882a0739", "shasum": "" }, "require": { @@ -879,8 +879,7 @@ "sabre/xml": ">=1.5 <3.0" }, "require-dev": { - "phpunit/phpunit": "> 4.8.35, <6.0.0", - "sabre/cs": "^1.0.0" + "phpunit/phpunit": "> 4.8.35, <6.0.0" }, "suggest": { "hoa/bench": "If you would like to run the benchmark scripts" @@ -954,7 +953,7 @@ "xCal", "xCard" ], - "time": "2018-04-20T07:22:50+00:00" + "time": "2019-02-19T13:05:37+00:00" }, { "name": "sabre/xml", @@ -1207,16 +1206,16 @@ }, { "name": "twbs/bootstrap", - "version": "v4.1.3", + "version": "v4.3.1", "source": { "type": "git", "url": "https://github.com/twbs/bootstrap.git", - "reference": "3b558734382ce58b51e5fc676453bfd53bba9201" + "reference": "8fa0d3010112dca5dd6dd501173415856001ba8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/3b558734382ce58b51e5fc676453bfd53bba9201", - "reference": "3b558734382ce58b51e5fc676453bfd53bba9201", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/8fa0d3010112dca5dd6dd501173415856001ba8b", + "reference": "8fa0d3010112dca5dd6dd501173415856001ba8b", "shasum": "" }, "replace": { @@ -1254,7 +1253,7 @@ "sass", "web" ], - "time": "2018-07-24T15:54:34+00:00" + "time": "2019-02-13T16:01:40+00:00" } ], "packages-dev": [ diff --git a/doc/admin/administrator_guide.md b/doc/admin/administrator_guide.md index 2b1c84180..c884bb0bd 100644 --- a/doc/admin/administrator_guide.md +++ b/doc/admin/administrator_guide.md @@ -1,4 +1,3 @@ - ### Overview $Projectname is more than a simple web application. It is a @@ -17,48 +16,47 @@ such as XAMPP and WAMP are not officially supported at this time however we welcome patches if you manage to get it working. ### Where to find more help -If you encounter problems or have issues not addressed in this documentation, +If you encounter problems or have issues not addressed in this documentation, please let us know via the [Github issue tracker](https://framagit.org/hubzilla/core/issues). Please be as clear as you can about your operating environment and provide as much detail as possible about any error messages you may see, so that we can prevent it from happening in the future. Due to the large variety of operating systems and PHP platforms in existence we may have only limited ability to debug your PHP installation or -acquire any missing modules * but we will do our best to solve any general code +acquire any missing modules, but we will do our best to solve any general code issues. -### Before you begin +### Before you begin #### Choose a domain name or subdomain name for your server -$Projectname can only be installed into the root of a domain or sub-domain, and can +$Projectname can only be installed into the root of a domain or sub-domain, and can not be installed using alternate TCP ports. #### Decide if you will use SSL and obtain an SSL certificate before software installation -You SHOULD use SSL. If you use SSL, you MUST use a "browser-valid" certificate. +You SHOULD use SSL. If you use SSL, you MUST use a "browser-valid" certificate. *You MUST NOT use self-signed certificates!* -Please test your certificate prior to installation. A web tool for testing your -certificate is available at "http://www.digicert.com/help/". When visiting your -site for the first time, please use the SSL ("https://") URL if SSL is available. -This will avoid problems later. The installation routine will not allow you to +Please test your certificate prior to installation. A web tool for testing your +certificate is available at "http://www.digicert.com/help/". When visiting your +site for the first time, please use the SSL ("https://") URL if SSL is available. +This will avoid problems later. The installation routine will not allow you to use a non browser-valid certificate. - -This restriction is incorporated because public posts from you may contain +This restriction is incorporated because public posts from you may contain references to images on your own hub. Other members viewing their stream on other hubs will get warnings if your certificate is not trusted by their web browser. This will confuse many people because this is a decentralised network -and they will get the warning about your hub while viewing their own hub and may -think their own hub has an issue. These warnings are very technical and scary to +and they will get the warning about your hub while viewing their own hub and may +think their own hub has an issue. These warnings are very technical and scary to some folks, many of whom will not know how to proceed except to follow the browser advice. This is disruptive to the community. That said, we recognise the issues surrounding the current certificate infrastructure and agree there are many -problems, but that doesn't change the requirement. +problems, but that doesn't change the requirement. Free "browser-valid" certificates are available from providers such as StartSSL -and LetsEncrypt. +and LetsEncrypt. If you do NOT use SSL, there may be a delay of up to a minute for the initial install script - while we check the SSL port to see if anything responds there. @@ -66,11 +64,11 @@ When communicating with new sites, $Projectname always attempts connection on th SSL port first, before falling back to a less secure connection. If you do not use SSL, your webserver MUST NOT listen on port 443 at all. -If you use LetsEncrypt to provide certificates and create a file under -.well-known/acme-challenge so that LetsEncrypt can verify your domain ownership, -please remove or rename the .well-known directory as soon as the certificate is +If you use LetsEncrypt to provide certificates and create a file under +.well-known/acme-challenge so that LetsEncrypt can verify your domain ownership, +please remove or rename the .well-known directory as soon as the certificate is generated. $Projectname will provide its own handler for ".well-known" services when -it is installed, and an existing directory in this location may prevent some of +it is installed, and an existing directory in this location may prevent some of these services from working correctly. This should not be a problem with Apache, but may be an issue with nginx or other web server platforms. @@ -82,20 +80,20 @@ There are several ways to deploy a new hub. * Automated deployment using an OpenShift virtual private server (VPS) ### Requirements -* Apache with mod-rewrite enabled and "AllowOverride All" so you can use a +* Apache with mod-rewrite enabled and "AllowOverride All" so you can use a local .htaccess file. Some folks have successfully used nginx and lighttpd. Example config scripts are available for these platforms in doc/install. - Apache and nginx have the most support. + Apache and nginx have the most support. -* PHP 5.5 or later. - * Note that on some shared hosting environments, the _command line_ version of -PHP might differ from the _webserver_ version +* PHP 7.1 or later. + * Note that on some shared hosting environments, the _command line_ + version of PHP might differ from the _webserver_ version -* PHP *command line* access with register_argc_argv set to true in the - php.ini file * and with no hosting provider restrictions on the use of +* PHP *command line* access with register_argc_argv set to true in the + php.ini file * and with no hosting provider restrictions on the use of exec() and proc_open(). -* curl, gd (with at least jpeg and png support), mysqli, mbstring, mcrypt, zip, +* curl, gd (with at least jpeg and png support), mysqli, mbstring, mcrypt, zip, and openssl extensions. The imagick extension is not required but desirable. * xml extension is required if you want webdav to work. @@ -106,7 +104,7 @@ PHP might differ from the _webserver_ version * ability to schedule jobs with cron. -* Installation into a top-level domain or sub-domain (without a +* Installation into a top-level domain or sub-domain (without a directory/path component in the URL) is REQUIRED. ### Manual Installation @@ -115,9 +113,9 @@ PHP might differ from the _webserver_ version If you copy the directory tree to your webserver, make sure that you include the hidden files like .htaccess. -If you are able to do so, we recommend using git to clone the source -repository rather than to use a packaged tar or zip file. This makes the -software much easier to update. The Linux command to clone the repository +If you are able to do so, we recommend using git to clone the source +repository rather than to use a packaged tar or zip file. This makes the +software much easier to update. The Linux command to clone the repository into a directory "mywebsite" would be: git clone https://framagit.org/hubzilla/core.git mywebsite @@ -126,7 +124,7 @@ and then you can pick up the latest changes at any time with: git pull -make sure folders ``store/[data]/smarty3`` and ``store`` exist and are +make sure folders ``store/[data]/smarty3`` and ``store`` exist and are writable by the webserver: mkdir -p "store/[data]/smarty3" @@ -150,7 +148,7 @@ web-based administrative tools to function: #### Official addons ##### Installation -Navigate to your website. Then you should clone the addon repository (separately). We'll give this repository a nickname of 'hzaddons'. You can pull in other hubzilla addon repositories by giving them different nicknames:: +Navigate to your website. Then you should clone the addon repository (separately). We'll give this repository a nickname of 'hzaddons'. You can pull in other hubzilla addon repositories by giving them different nicknames: cd mywebsite util/add_addon_repo https://framagit.org/hubzilla/addons.git hzaddons @@ -161,9 +159,9 @@ For keeping the addon tree updated, you should be on your top level website dire cd mywebsite util/update_addon_repo hzaddons -Create searchable representations of the online documentation. You may do this -any time that the documentation is updated : - +Create searchable representations of the online documentation. You may do this +any time that the documentation is updated : + cd mywebsite util/importdoc @@ -203,45 +201,28 @@ We recommend the following addons be installed on all public sites: Several web communities have begun to converge using common protocols. The protocols involved are somewhat limited in their abilities. The GNU-Social protocol for instance offers no privacy modes, and the Diaspora protocol is somewhat restrictive in what kinds of communications are allowed. All comments must be signed in a very unique manner by the original author. The ActivityPub protocol is also being considered and may be supported at a future date. No other existing protocol supports nomadic location as used by this project. This presents some support challenges as some features work with some networks and don't work with others. Nevertheless the federation protocols allow connections to be made to a much larger community of people worldwide. They are provided as addons. -> diaspora - The Diaspora Protocol used by Diaspora and Friendica. You should enable 'Diaspora Statistics' (statistics) first to enable all the available features. +* diaspora - The Diaspora Protocol used by Diaspora and Friendica. You should enable 'Diaspora Statistics' (statistics) first to enable all the available features. -> gnusoc - The GNU-Social Protocol, used by GNU-Social, Mastodon and several other communities. This addon requires you first install the 'pubsubhubbub' service (also an addon). +* gnusoc - The GNU-Social Protocol, used by GNU-Social, Mastodon and several other communities. This addon requires you first install the 'pubsubhubbub' service (also an addon). Each member of your site must choose whether or not to allow these protocols individually as they may conflict with several desirable core features and abilities of this software (such as channel migration and cloning). They do this from their 'Settings -> Feature/Addon Settings' page. The administrator may also set the following: util/config system.diaspora_allowed 1 util/config system.gnusoc_allowed 1 -and enable these protocols automatically for all newly created channels. - - - - - - -### Techlevels - -We've implemented several different mechanisms in order to reduce the apparent complexity and learning curve presented to new members. At the same time, we do not wish to limit any functionality for people who are able to grasp some slightly advanced technical technical features. The first mechanism was to move several features to an optional 'Features' page where they could be enabled at will; with the default interface kept somewhat lean. - -The problem we had now is that the number of features began to grow dramatically, and the Feature page is daunting in possibilities. There are also features present which probably should not be available to all members, but may be extremely useful to those with technical backgrounds. - -The techlevels seeeks to remedy this by grouping features within different levels of technical ability; starting at 0 (uncomfortable with technology), and up to 5 (Unix wizard or equivalent). - -When a new member registers, their account is provided a techlevel setting of 0. On the account settings page they may change this to any available level. A higher level opens more advanced features and possible interactions. - -The account administrator may also lock a particular level, lock a maximum level, or change/re-arrange the features available to any level. Those with the minimum level are typically not very exploratory and are unlikely to discover the advanced modes. This is by design. Those that look around and desire more interactions will find them. In the absence of administrator defaults they may choose any level. As they look at the features available to the level in question, it is generally expected that they will discover some features are beyond their comprehension and it is hoped they will back off to a level where the interface and features are comfortable to their skill level. +and enable these protocols automatically for all newly created channels. ### Service Classes Service classes allow you to set limits on system resources by limiting what individual -accounts can do, including file storage and top-level post limits. Define custom service -classes according to your needs in the `.htconfig.php` file. For example, create +accounts can do, including file storage and top-level post limits. Define custom service +classes according to your needs in the `.htconfig.php` file. For example, create a _standard_ and _premium_ class using the following lines: // Service classes - + App::$config['system']['default_service_class']='standard'; // this is the default service class that is attached to every new account - + // configuration for standard service class App::$config['service_class']['standard'] = array('photo_upload_limit'=>2097152, // total photo storage limit per channel (here 2MB) @@ -251,7 +232,7 @@ a _standard_ and _premium_ class using the following lines: 'total_channels' =>100, // number of channels the user can add, other users can still add this channel, even if the limit is reached 'attach_upload_limit' =>2097152, // total attachment storage limit per channel (here 2MB) 'chatters_inroom' =>20); - + // configuration for premium service class App::$config['service_class']['premium'] = array('photo_upload_limit'=>20000000000, // total photo storage limit per channel (here 20GB) @@ -262,7 +243,7 @@ a _standard_ and _premium_ class using the following lines: 'attach_upload_limit' =>20000000000, // total attachment storage limit per channel (here 20GB) 'chatters_inroom' =>100); -To apply a service class to an existing account, use the command line utility from the +To apply a service class to an existing account, use the command line utility from the web root: `util/service_class` @@ -298,11 +279,11 @@ set the account that owns channel 'blogchan' to service class 'firstclass' (with * access_tokens - maximum number of Guest Access Tokens per channel ### Theme management -#### Repo management example +#### Repo management example 1. Navigate to your hub web root ``` - root@hub:/root# cd /var/www + root@hub:/root# cd /var/www ``` 2. Add the theme repo and give it a name @@ -319,70 +300,136 @@ set the account that owns channel 'blogchan' to service class 'firstclass' (with #### Keywords -There is a "tag cloud" of keywords that can appear on the channel directory page. -If you wish to hide these keywords, which are drawn from the directory server, you +There is a "tag cloud" of keywords that can appear on the channel directory page. +If you wish to hide these keywords, which are drawn from the directory server, you can use the *config* tool: util/config system disable_directory_keywords 1 - -If your hub is in the standalone mode because you do not wish to connect to the -global grid, you may instead ensure the the _directory_server_ system option is + +If your hub is in the standalone mode because you do not wish to connect to the +global grid, you may instead ensure the the _directory_server_ system option is empty: util/config system directory_server "" - ### Administration #### Site Administration -Administration of the website is commonly done through the admin webpage located at /admin on your website. In order to access this page you must have administration rights to the server. Administration rights are granted to the first account to register on your site, **provided** the email address of that account exactly matches the email address you provided as the administrator's email address during setup. +Administration of the website is commonly done through the admin webpage located at /admin on your website. In order to access this page you must have administration rights to the server. Administration rights are granted to the first account to register on your site, **provided** the email address of that account exactly matches the email address you provided as the administrator's email address during setup. -There are several ways that this can fail and leave the system without an administrator account, for instance if the first account that was created provided a different email address than the administrator email address that was supplied during setup. +There are several ways that this can fail and leave the system without an administrator account, for instance if the first account that was created provided a different email address than the administrator email address that was supplied during setup. For security reasons there is no web page or interface on the system which will give you administrator access. If you need to correct a situation where a system has no administrator account it **must** be done by editing the account table in the database. There is no other way. To do this, you will need to locate the entry in the account table which belongs to the desired administrator, and set 'account_roles' for that entry to 4096. You will then be able to access the admin page from your system's profile menu or directly via /admin . -A hub can have multiple admins and there is no limit to how administrators you can have. Repeat the above process for every account you wish to provide with administration rights. - +A hub can have multiple admins and there is no limit to how administrators you can have. Repeat the above process for every account you wish to provide with administration rights. ### Troubleshooting #### Log files -The system logfile is an extremely useful resource for tracking down things that go wrong. This can be enabled in the admin/log configuration page. A loglevel setting of LOGGER_DEBUG is preferred for stable production sites. Most things that go wrong with communications or storage are listed here. A setting of LOGGER_DATA provides [b]much[/b] more detail, but may fill your disk. In either case we recommend the use of logrotate on your operating system to cycle logs and discard older entries. +The system logfile is an extremely useful resource for tracking down +things that go wrong. This can be enabled in the admin/log +configuration page. A loglevel setting of `LOGGER_DEBUG` is preferred +for stable production sites. Most things that go wrong with +communications or storage are listed here. A setting of LOGGER_DATA +provides *much* more detail, but may fill your disk. In either +case we recommend the use of logrotate on your operating system to +cycle logs and discard older entries. -At the bottom of your .htconfig.php file are several lines (commented out) which enable PHP error logging. This reports issues with code syntax and executing the code and is the first place you should look for issues which result in a "white screen" or blank page. This is typically the result of code/syntax problems. -Database errors are reported to the system logfile, but we've found it useful to have a file in your top-level directory called dbfail.out which [b]only[/b] collects database related issues. If the file exists and is writable, database errors will be logged to it as well as to the system logfile. +At the bottom of your .htconfig.php file are several lines (commented +out) which enable PHP error logging. This reports issues with code +syntax and executing the code and is the first place you should look +for issues which result in a "white screen" or blank page. This is +typically the result of code/syntax problems. Database errors are +reported to the system logfile, but we've found it useful to have a +file in your top-level directory called dbfail.out which *only* +collects database related issues. If the file exists and is writable, +database errors will be logged to it as well as to the system logfile. -In the case of "500" errors, the issues may often be logged in your webserver logs, often /var/log/apache2/error.log or something similar. Consult your operating system documentation. +In the case of "500" errors, the issues may often be logged in your +webserver logs, often /var/log/apache2/error.log or something +similar. Consult your operating system documentation. There are three different log facilities. -**The first is the database failure log**. This is only used if you create a file called specifically 'dbfail.out' in the root folder of your website and make it write-able by the web server. If we have any database failed queries, they are all reported here. They generally indicate typos in our queries, but also occur if the database server disconnects or tables get corrupted. On rare occasions we'll see race conditions in here where two processes tried to create an xchan or cache entry with the same ID. Any other errors (especially persistent errors) should be investigated. +**The first is the database failure log**. This is only used if you + create a file called specifically `dbfail.out` in the root folder of + your website and make it write-able by the web server. If we have + any database failed queries, they are all reported here. They + generally indicate typos in our queries, but also occur if the + database server disconnects or tables get corrupted. On rare + occasions we'll see race conditions in here where two processes + tried to create an xchan or cache entry with the same ID. Any other + errors (especially persistent errors) should be investigated. -**The second is the PHP error log**. This is created by the language processor and only reports issues in the language environment. Again these can be syntax errors or programming errors, but these generally are fatal and result in a "white screen of death"; e.g. PHP terminates. You should probably look at this file if something goes wrong that doesn't result in a white screen of death, but it isn't uncommon for this file to be empty for days on end. +**The second is the PHP error log**. This is created by the language + processor and only reports issues in the language environment. Again + these can be syntax errors or programming errors, but these + generally are fatal and result in a "white screen of death"; + e.g. PHP terminates. You should probably look at this file if + something goes wrong that doesn't result in a white screen of death, + but it isn't uncommon for this file to be empty for days on end. -There are some lines at the bottom of the supplied .htconfig.php file; which if uncommented will enable a PHP error log (*extremely* useful for finding the source of white screen failures). This isn't done by default due to potential issues with logfile ownership and write permissions and the fact that there is no logfile rotation by default. - + There are some lines at the bottom of the supplied `.htconfig.php` + file; which if uncommented will enable a PHP error log (*extremely* + useful for finding the source of white screen failures). This isn't + done by default due to potential issues with logfile ownership and + write permissions and the fact that there is no logfile rotation by + default. -**The third is the "application log"**. This is used by $Projectname to report what is going on in the program and usually reports any difficulties or unexpected data we received. It also occasionally reports "heartbeat" status messages to indicate that we reached a certain point in a script. **This** is the most important log file to us, as we create it ourself for the sole purpose of reporting the status of background tasks and anything that seems weird or out of place. It may not be fatal, but maybe just unexpected. If you're performing a task and there's a problem, let us know what is in this file when the problem occurred. (Please don't send me 100M dumps you'll only piss me off). Just a few relevant lines so I can rule out a few hundred thousand lines of code and concentrate on where the problem starts showing up. +**The third is the "application log"**. This is used by $Projectname + to report what is going on in the program and usually reports any + difficulties or unexpected data we received. It also occasionally + reports "heartbeat" status messages to indicate that we reached a + certain point in a script. **This** is the most important log file + to us, as we create it ourself for the sole purpose of reporting the + status of background tasks and anything that seems weird or out of + place. It may not be fatal, but maybe just unexpected. If you're + performing a task and there's a problem, let us know what is in this + file when the problem occurred. (Please don't send me 100M dumps + you'll only piss me off). Just a few relevant lines so I can rule + out a few hundred thousand lines of code and concentrate on where + the problem starts showing up. -These are your site logs, not mine. We report serious issues at any log level. I highly recommend 'DEBUG' log level for most sites - which provides a bit of additional info and doesn't create huge logfiles. When there's a problem which defies all attempts to track, you might wish to use DATA log level for a short period of time to capture all the detail of what structures we were dealing with at the time. This log level will use a lot of space so is recommended only for brief periods or for developer test sites. +These are your site logs, not mine. We report serious issues at any +log level. I highly recommend `DEBUG` log level for most sites - which +provides a bit of additional info and doesn't create huge +logfiles. When there's a problem which defies all attempts to track, +you might wish to use `DATA` log level for a short period of time to +capture all the detail of what structures we were dealing with at the +time. This log level will use a lot of space so is recommended only +for brief periods or for developer test sites. -I recommend configuring logrotate for both the php log and the application log. I usually have a look at dbfail.out every week or two, fix any issues reported and then starting over with a fresh file. Likewise with the PHP logfile. I refer to it once in a while to see if there's something that needs fixing. +I recommend configuring logrotate for both the php log and the +application log. I usually have a look at dbfail.out every week or +two, fix any issues reported and then starting over with a fresh +file. Likewise with the PHP logfile. I refer to it once in a while to +see if there's something that needs fixing. + +If something goes wrong, and it's not a fatal error, I look at the +application logfile. Often I will -If something goes wrong, and it's not a fatal error, I look at the application logfile. Often I will ``` -tail -f logfile.out +tail -f logfile.out ``` -While repeating an operation that has problems. Often I'll insert extra logging statements in the code if there isn't any hint what's going wrong. Even something as simple as "got here" or printing out the value of a variable that might be suspect. You can do this too - in fact I encourage you to do so. Once you've found what you need to find, you can +While repeating an operation that has problems. Often I'll insert +extra logging statements in the code if there isn't any hint what's +going wrong. Even something as simple as "got here" or printing out +the value of a variable that might be suspect. You can do this too - +in fact I encourage you to do so. Once you've found what you need to +find, you can ``` git checkout file.php ``` -To immediately clear out all the extra logging stuff you added. Use the information from this log and any detail you can provide from your investigation of the problem to file your bug report - unless your analysis points to the source of the problem. In that case, just fix it. +To immediately clear out all the extra logging stuff you added. Use +the information from this log and any detail you can provide from your +investigation of the problem to file your bug report - unless your +analysis points to the source of the problem. In that case, just fix +it. ##### Rotating log files @@ -390,13 +437,25 @@ To immediately clear out all the extra logging stuff you added. Use the informa 1. Create a directory in your web root called `log` with webserver write permissions 1. Go to the **logrot** admin settings and enter this folder name as well as the max size and number of retained log files. - #### Reporting issues -When reporting issues, please try to provide as much detail as may be necessary for developers to reproduce the issue and provide the complete text of all error messages. - -We encourage you to try to the best of your abilities to use these logs combined with the source code in your possession to troubleshoot issues and find their cause. The community is often able to help, but only you have access to your site logfiles and it is considered a security risk to share them. - -If a code issue has been uncovered, please report it on the project bugtracker (https://framagit.org/hubzilla/core/issues). Again provide as much detail as possible to avoid us going back and forth asking questions about your configuration or how to duplicate the problem, so that we can get right to the problem and figure out what to do about it. You are also welcome to offer your own solutions and submit patches. In fact we encourage this as we are all volunteers and have little spare time available. The more people that help, the easier the workload for everybody. It's OK if your solution isn't perfect. Every little bit helps and perhaps we can improve on it. +When reporting issues, please try to provide as much detail as may be +necessary for developers to reproduce the issue and provide the +complete text of all error messages. +We encourage you to try to the best of your abilities to use these +logs combined with the source code in your possession to troubleshoot +issues and find their cause. The community is often able to help, but +only you have access to your site logfiles and it is considered a +security risk to share them. +If a code issue has been uncovered, please report it on the project +bugtracker (https://framagit.org/hubzilla/core/issues). Again provide +as much detail as possible to avoid us going back and forth asking +questions about your configuration or how to duplicate the problem, so +that we can get right to the problem and figure out what to do about +it. You are also welcome to offer your own solutions and submit +patches. In fact we encourage this as we are all volunteers and have +little spare time available. The more people that help, the easier the +workload for everybody. It's OK if your solution isn't perfect. Every +little bit helps and perhaps we can improve on it. diff --git a/doc/hidden_configs.bb b/doc/hidden_configs.bb index 8b5429deb..dc3906df1 100644 --- a/doc/hidden_configs.bb +++ b/doc/hidden_configs.bb @@ -51,6 +51,7 @@ Options are: [*= system.email_notify_icon_url ] URL of image (32x32) to display in email notifications (HTML bodies). [*= system.expire_delivery_reports ] Expiration in days for delivery reports - default 10 [*= system.expire_limit ] Don't expire any more than this number of posts per channel per expiration run to keep from exhausting memory. Default 5000. + [*= system.filesystem_storage_thumbnails ] If '1', use filesystem instead SQL database to store thumbnails. Default is '0'. Introduced in 4.2 [*= system.hidden_version_siteinfo ] If true, do not report the software version on siteinfo pages (system.hide_version also hides the version on these pages, this setting *only* hides the version on siteinfo pages). [*= system.hide_help ] Don't display help documentation link in nav bar [*= system.hide_in_statistics ] Tell the red statistics servers to completely hide this hub in hub lists. @@ -79,7 +80,7 @@ Options are: [*= system.startpage ] Set the default page to be taken to after a login for all channels at this website. Can be overwritten by user settings. [*= system.sys_expire_days ] How many days to keep discovered public content from other sites [*= system.taganyone ] Allow the @mention tagging of anyone whether you are connected or not. - [*= system.tempdir ] Place to store temporary files (currently unused), default is defined in the PHP configuration + [*= system.tempdir ] Place to store temporary files (currently unused), default is defined in the PHP configuration. [*= system.tos_url ] Set an alternative link for the ToS location. [*= system.transport_security_header ] if non-zero and SSL is being used, include a strict-transport-security header on webpages [*= system.uploaddir ] Location to upload files (default is system.tempdir, currently used only by js_upload plugin) diff --git a/include/attach.php b/include/attach.php index f6594b154..f169e0669 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1521,6 +1521,17 @@ function attach_drop_photo($channel_id,$resource) { if($x) { drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true); } + + $r = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1", + dbesc($resource), + intval($channel_id) + ); + if($r) { + foreach($r as $i) { + @unlink(dbunescbin($i['content'])); + } + } + q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'", intval($channel_id), dbesc($resource) diff --git a/include/bbcode.php b/include/bbcode.php index 36f943e46..485a1f5b2 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -87,12 +87,11 @@ function nakedoembed($match) { $strip_url = strip_escaped_zids($url); - $o = oembed_fetch_url($strip_url); - - if ($o['type'] == 'error') - return str_replace($url,$strip_url,$match[0]); - - return '[embed]' . $strip_url . '[/embed]'; + // this function no longer performs oembed on naked links + // because they author may have created naked links intentionally. + // Now it just strips zids on naked links. + + return str_replace($url,$strip_url,$match[0]); } function tryzrlaudio($match) { @@ -986,17 +985,22 @@ function bbcode($Text, $options = []) { // leave open the posibility of [map=something] // this is replaced in prepare_body() which has knowledge of the item location - - if (strpos($Text,'[/map]') !== false) { - $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text); + if ($cache) { + $Text = str_replace([ '[map]','[/map]' ], [ '','' ], $Text); + $Text = preg_replace('/\[map=(.*?)\]/ism','$1',$Text); } - if (strpos($Text,'[map=') !== false) { - $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text); + else { + if (strpos($Text,'[/map]') !== false) { + $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism", 'bb_map_location', $Text); + } + if (strpos($Text,'[map=') !== false) { + $Text = preg_replace_callback("/\[map=(.*?)\]/ism", 'bb_map_coords', $Text); + } + if (strpos($Text,'[map]') !== false) { + $Text = preg_replace("/\[map\]/", '
', $Text); + } } - if (strpos($Text,'[map]') !== false) { - $Text = preg_replace("/\[map\]/", '
', $Text); - } - + // Check for bold text if (strpos($Text,'[b]') !== false) { $Text = preg_replace("(\[b\](.*?)\[\/b\])ism", '$1', $Text); diff --git a/include/connections.php b/include/connections.php index d97ea3887..e942503f0 100644 --- a/include/connections.php +++ b/include/connections.php @@ -373,19 +373,46 @@ function contact_remove($channel_id, $abook_id) { if(intval($abook['abook_self'])) return false; - $r = q("select id from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0", + $r = q("select id, parent from item where (owner_xchan = '%s' or author_xchan = '%s') and uid = %d and item_retained = 0 and item_starred = 0", dbesc($abook['abook_xchan']), dbesc($abook['abook_xchan']), intval($channel_id) ); if($r) { + $already_saved = []; foreach($r as $rr) { - $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", + $w = $x = $y = null; + + // optimise so we only process newly seen parent items + if (in_array($rr['parent'],$already_saved)) { + continue; + } + // if this isn't the parent, fetch the parent's item_retained and item_starred to see if the conversation + // should be retained + if($rr['id'] != $rr['parent']) { + $w = q("select id, item_retained, item_starred from item where id = %d", + intval($rr['parent']) + ); + if($w) { + // see if the conversation was filed + $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", + intval(TERM_OBJ_POST), + intval($w[0]['id']), + intval(TERM_FILE) + ); + if (intval($w[0]['item_retained']) || intval($w[0]['item_starred']) || $x) { + $already_saved[] = $rr['parent']; + continue; + } + } + } + // see if this item was filed + $y = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", intval(TERM_OBJ_POST), intval($rr['id']), intval(TERM_FILE) ); - if($x) { + if ($y) { continue; } drop_item($rr['id'],false); diff --git a/include/datetime.php b/include/datetime.php index 3a07f1ccf..ef0927ea4 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -516,13 +516,14 @@ function update_birthdays() { 'event_xchan' => $rr['xchan_hash'], 'dtstart' => datetime_convert('UTC', 'UTC', $rr['abook_dob']), 'dtend' => datetime_convert('UTC', 'UTC', $rr['abook_dob'] . ' + 1 day '), - 'adjust' => intval(feature_enabled($rr['abook_channel'],'smart_birthdays')), + 'adjust' => 0, 'summary' => sprintf( t('%1$s\'s birthday'), $rr['xchan_name']), 'description' => sprintf( t('Happy Birthday %1$s'), '[zrl=' . $rr['xchan_url'] . ']' . $rr['xchan_name'] . '[/zrl]'), 'etype' => 'birthday', ]; $z = event_store_event($ev); + if ($z) { $item_id = event_store_item($ev, $z); q("update abook set abook_dob = '%s' where abook_id = %d", diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index ee0e06a91..cfb208e2d 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -485,3 +485,28 @@ function db_columns($table) { return []; } + + +function db_indexes($table) { + + if($table) { + if(ACTIVE_DBTYPE === DBTYPE_POSTGRES) { + $r = q("SELECT indexname from pg_indexes where tablename = '%s'", + dbesc($table) + ); + if($r) { + return ids_to_array($r,'indexname'); + } + } + else { + $r = q("show index from %s", + dbesc($table) + ); + if($r) { + return ids_to_array($r,'Key_name'); + } + } + } + + return []; +} diff --git a/include/dba/dba_pdo.php b/include/dba/dba_pdo.php index ef8063428..0279342ec 100755 --- a/include/dba/dba_pdo.php +++ b/include/dba/dba_pdo.php @@ -19,7 +19,7 @@ class dba_pdo extends dba_driver { $this->driver_dbtype = $scheme; if(strpbrk($server,':;')) { - $dsn = $server; + $dsn = $this->driver_dbtype . ':unix_socket=' . trim($server, ':;'); } else { $dsn = $this->driver_dbtype . ':host=' . $server . (intval($port) ? ';port=' . $port : ''); diff --git a/include/event.php b/include/event.php index 77118c329..6689919cf 100644 --- a/include/event.php +++ b/include/event.php @@ -27,6 +27,7 @@ function format_event_html($ev) { if(! ((is_array($ev)) && count($ev))) return ''; + $tz = (($ev['timezone']) ? $ev['timezone'] : 'UTC'); $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8:01 AM @@ -39,7 +40,7 @@ function format_event_html($ev) { $o .= '
' . t('Starts:') . ' ' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), + . (($ev['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $ev['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $ev['dtstart'] , $bd_format))) @@ -49,7 +50,7 @@ function format_event_html($ev) { $o .= '
' . t('Finishes:') . ' ' - . (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), + . (($ev['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $ev['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $ev['dtend'] , $bd_format ))) @@ -75,17 +76,35 @@ function format_event_obj($jobject) { //ensure compatibility with older items - this check can be removed at a later point if(array_key_exists('description', $object)) { - $bd_format = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM + $tz = (($object['timezone']) ? $object['timezone'] : 'UTC'); + $allday = (($object['adjust']) ? false : true); + + $dtstart = new DateTime($object['dtstart']); + $dtend = new DateTime($object['dtend']); + $dtdiff = $dtstart->diff($dtend); + + if($allday && ($dtdiff->days < 2)) + $oneday = true; + + if($allday && !$oneday) { + // Subtract one day from the end date so we can use the "first day - last day" format for display. + $dtend->modify('-1 day'); + $object['dtend'] = datetime_convert('UTC', 'UTC', $dtend->format('Y-m-d H:i:s')); + } + + $bd_format = (($allday) ? t('l F d, Y') : t('l F d, Y \@ g:i A')); // Friday January 18, 2011 @ 8:01 AM or Friday January 18, 2011 for allday events $event['header'] = replace_macros(get_markup_template('event_item_header.tpl'),array( '$title' => zidify_links(smilies(bbcode($object['title']))), - '$dtstart_label' => t('Starts:'), - '$dtstart_title' => datetime_convert('UTC', 'UTC', $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))), + '$dtstart_label' => t('Start:'), + '$dtstart_title' => datetime_convert($tz, date_default_timezone_get(), $object['dtstart'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtstart_dt' => (($object['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $object['dtstart'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtstart'] , $bd_format))), '$finish' => (($object['nofinish']) ? false : true), - '$dtend_label' => t('Finishes:'), - '$dtend_title' => datetime_convert('UTC','UTC',$object['dtend'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), - '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $object['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtend'] , $bd_format ))) + '$dtend_label' => t('End:'), + '$dtend_title' => datetime_convert($tz, date_default_timezone_get(), $object['dtend'], (($object['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )), + '$dtend_dt' => (($object['adjust']) ? day_translate(datetime_convert($tz, date_default_timezone_get(), $object['dtend'] , $bd_format )) : day_translate(datetime_convert('UTC', 'UTC', $object['dtend'] , $bd_format ))), + '$allday' => $allday, + '$oneday' => $oneday )); $event['content'] = replace_macros(get_markup_template('event_item_content.tpl'),array( @@ -125,6 +144,12 @@ function format_event_ical($ev) { if($ev['etype'] === 'task') return format_todo_ical($ev); + $tz = get_iconfig($ev['item_id'], 'event', 'timezone'); + if(! $tz) + $tz = 'UTC'; + + $tzid = ';TZID=' . $tz; + $o = ''; $o .= "\r\nBEGIN:VEVENT"; @@ -132,10 +157,19 @@ function format_event_ical($ev) { $o .= "\r\nCREATED:" . datetime_convert('UTC','UTC', $ev['created'],'Ymd\\THis\\Z'); $o .= "\r\nLAST-MODIFIED:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); $o .= "\r\nDTSTAMP:" . datetime_convert('UTC','UTC', $ev['edited'],'Ymd\\THis\\Z'); - if($ev['dtstart']) - $o .= "\r\nDTSTART:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); - if($ev['dtend'] && ! $ev['nofinish']) - $o .= "\r\nDTEND:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd\\THis' . (($ev['adjust']) ? '\\Z' : '')); + + if($ev['adjust']) { + if($ev['dtstart']) + $o .= "\r\nDTSTART$tzid:" . datetime_convert($tz,'UTC', $ev['dtstart'],'Ymd\\THis\\Z'); + if($ev['dtend'] && ! $ev['nofinish']) + $o .= "\r\nDTEND$tzid:" . datetime_convert($tz,'UTC', $ev['dtend'],'Ymd\\THis\\Z'); + } + else { + if($ev['dtstart']) + $o .= "\r\nDTSTART;VALUE=DATE:" . datetime_convert('UTC','UTC', $ev['dtstart'],'Ymd'); + if($ev['dtend'] && ! $ev['nofinish']) + $o .= "\r\nDTEND;VALUE=DATE:" . datetime_convert('UTC','UTC', $ev['dtend'],'Ymd'); + } if($ev['summary']) { $o .= "\r\nSUMMARY:" . format_ical_text($ev['summary']); $o .= "\r\nX-ZOT-SUMMARY:" . format_ical_sourcetext($ev['summary']); @@ -723,17 +757,9 @@ function parse_vobject($ical, $type) { function parse_ical_file($f,$uid) { - require_once('vendor/autoload.php'); $s = @file_get_contents($f); - // Change the current timezone to something besides UTC. - // Doesn't matter what it is, as long as it isn't UTC. - // Save the current timezone so we can reset it when we're done processing. - - $saved_timezone = date_default_timezone_get(); - date_default_timezone_set('Australia/Sydney'); - $ical = VObject\Reader::read($s); if($ical) { @@ -749,8 +775,6 @@ function parse_ical_file($f,$uid) { } } - date_default_timezone_set($saved_timezone); - if($ical) return true; @@ -782,12 +806,23 @@ function event_import_ical($ical, $uid) { // logger('dtstart: ' . var_export($dtstart,true)); - $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['timezone'] = 'UTC'; + + // Try to get an usable olson format timezone + if($ev['adjust']) { + //TODO: we should pass the vcalendar to getTimeZone() to be more accurate + // we do not have it here since parse_ical_file() is passing the vevent only. + $timezone_obj = \Sabre\VObject\TimeZoneUtil::getTimeZone($ical->DTSTART['TZID']); + $timezone = $timezone_obj->getName(); + $ev['timezone'] = $timezone; + } + + $ev['dtstart'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),$ev['timezone'], $dtstart->format(\DateTime::W3C)); if(isset($ical->DTEND)) { $dtend = $ical->DTEND->getDateTime(); - $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),'UTC', + $ev['dtend'] = datetime_convert((($ev['adjust']) ? 'UTC' : date_default_timezone_get()),$ev['timezone'], $dtend->format(\DateTime::W3C)); } else { @@ -1042,6 +1077,7 @@ function event_store_item($arr, $event) { 'type' => ACTIVITY_OBJ_EVENT, 'id' => z_root() . '/event/' . $r[0]['resource_id'], 'title' => $arr['summary'], + 'timezone' => $arr['timezone'], 'dtstart' => $arr['dtstart'], 'dtend' => $arr['dtend'], 'nofinish' => $arr['nofinish'], @@ -1107,6 +1143,8 @@ function event_store_item($arr, $event) { } $item_id = $r[0]['id']; + set_iconfig($item_id, 'event', 'timezone', $arr['timezone'], true); + /** * @hooks event_updated * Called when an event record is modified. @@ -1163,7 +1201,7 @@ function event_store_item($arr, $event) { $item_arr['item_thread_top'] = $item_thread_top; $attach = array(array( - 'href' => z_root() . '/events/ical/' . urlencode($event['event_hash']), + 'href' => z_root() . '/channel_calendar/ical/' . urlencode($event['event_hash']), 'length' => 0, 'type' => 'text/calendar', 'title' => t('event') . '-' . $event['event_hash'], @@ -1185,7 +1223,7 @@ function event_store_item($arr, $event) { // otherwise we'll fallback to /display/$message_id if($wall) - $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . urlencode($item_arr['mid']); + $item_arr['plink'] = z_root() . '/channel/' . $z[0]['channel_address'] . '/?f=&mid=' . gen_link_id($item_arr['mid']); else $item_arr['plink'] = z_root() . '/display/' . gen_link_id($item_arr['mid']); @@ -1197,6 +1235,7 @@ function event_store_item($arr, $event) { 'type' => ACTIVITY_OBJ_EVENT, 'id' => z_root() . '/event/' . $event['event_hash'], 'title' => $arr['summary'], + 'timezone' => $arr['timezone'], 'dtstart' => $arr['dtstart'], 'dtend' => $arr['dtend'], 'nofinish' => $arr['nofinish'], @@ -1223,6 +1262,7 @@ function event_store_item($arr, $event) { // activities refer to the item message_id as the parent. set_iconfig($item_arr, 'system','event_id',$event['event_hash'],true); + set_iconfig($item_arr, 'event','timezone',$arr['timezone'],true); $res = item_store($item_arr); @@ -1284,6 +1324,10 @@ function cdav_principal($uri) { } function cdav_perms($needle, $haystack, $check_rw = false) { + + if($needle == 'channel_calendar') + return true; + foreach ($haystack as $item) { if($check_rw) { if(is_array($item['id'])) { diff --git a/include/features.php b/include/features.php index d021f9394..9528d3418 100644 --- a/include/features.php +++ b/include/features.php @@ -79,7 +79,7 @@ function get_features($filtered = true, $level = (-1)) { 'calendar' => [ - t('CalDAV'), + t('Calendar'), [ 'cal_first_day', @@ -87,6 +87,14 @@ function get_features($filtered = true, $level = (-1)) { t('Default is Sunday'), false, get_config('feature_lock','cal_first_day') + ], + + [ + 'event_tz_select', + t('Event Timezone Selection'), + t('Allow event creation in timezones other than your own.'), + false, + get_config('feature_lock','event_tz_select'), ] ], @@ -167,6 +175,14 @@ function get_features($filtered = true, $level = (-1)) { t('Ability to mark special posts with a star indicator'), false, get_config('feature_lock','star_posts'), + ], + + [ + 'reply_to', + t('Reply on comment'), + t('Ability to reply on selected comment'), + false, + get_config('feature_lock','reply_to'), ] ], @@ -274,22 +290,6 @@ function get_features($filtered = true, $level = (-1)) { t('Default is Sunday'), false, get_config('feature_lock','events_cal_first_day') - ], - - [ - 'smart_birthdays', - t('Smart Birthdays'), - t('Make birthday events timezone aware in case your friends are scattered across the planet.'), - true, - get_config('feature_lock','smart_birthdays'), - ], - - [ - 'event_tz_select', - t('Event Timezone Selection'), - t('Allow event creation in timezones other than your own.'), - false, - get_config('feature_lock','event_tz_select'), ] ], diff --git a/include/follow.php b/include/follow.php index 1b35f1b32..50b952881 100644 --- a/include/follow.php +++ b/include/follow.php @@ -142,7 +142,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) $sql_options = (($protocol) ? " and xchan_network = '" . dbesc($protocol) . "' " : ''); - $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' $sql_options limit 1", + $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' $sql_options ", dbesc($url), dbesc($url) ); @@ -169,18 +169,19 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) } if($wf || $d) { - $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s' limit 1", + $r = q("select * from xchan where xchan_hash = '%s' or xchan_url = '%s'", dbesc(($wf) ? $wf : $url), dbesc($url) ); } } + $xchan = zot_record_preferred($r,'xchan_network'); + // if discovery was a success we should have an xchan record in $r - if($r) { - $xchan = $r[0]; - $xchan_hash = $r[0]['xchan_hash']; + if($xchan) { + $xchan_hash = $xchan['xchan_hash']; $their_perms = 0; } } @@ -191,9 +192,9 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) return $result; } - $allowed = (($is_zot || in_array($r[0]['xchan_network'],['rss','zot6'])) ? 1 : 0); + $allowed = (($is_zot || in_array($xchan['xchan_network'],['rss','zot6'])) ? 1 : 0); - $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $r[0], 'allowed' => $allowed, 'singleton' => 0); + $x = array('channel_id' => $uid, 'follow_address' => $url, 'xchan' => $xchan, 'allowed' => $allowed, 'singleton' => 0); call_hooks('follow_allow',$x); diff --git a/include/html2bbcode.php b/include/html2bbcode.php index 1a03fbdaf..c916421b8 100644 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -219,8 +219,7 @@ function html2bbcode($message) $message = $doc->saveHTML(); - // I'm removing something really disturbing - // Don't know exactly what it is + // I'm removing the UTF-8 encoding of a NO-BREAK SPACE codepoint $message = str_replace(chr(194).chr(160), ' ', $message); $message = str_replace(" ", " ", $message); diff --git a/include/import.php b/include/import.php index 7a1e9aa55..4da0d1a0b 100644 --- a/include/import.php +++ b/include/import.php @@ -94,7 +94,8 @@ function import_channel($channel, $account_id, $seize, $newname = '') { 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', 'channel_a_delegate', 'perm_limits', 'channel_password', 'channel_salt', - 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system' + 'channel_moved', 'channel_removed', 'channel_deleted', 'channel_system', + 'channel_r_photos', 'channel_w_photos' ]; $clean = array(); @@ -896,9 +897,9 @@ function import_menus($channel, $menus) { $m['menu_name'] = $menu['pagetitle']; $m['menu_desc'] = $menu['desc']; if($menu['created']) - $m['menu_created'] = datetime_convert($menu['created']); + $m['menu_created'] = datetime_convert('UTC','UTC',$menu['created']); if($menu['edited']) - $m['menu_edited'] = datetime_convert($menu['edited']); + $m['menu_edited'] = datetime_convert('UTC','UTC',$menu['edited']); $m['menu_flags'] = 0; if($menu['flags']) { @@ -954,9 +955,9 @@ function sync_menus($channel, $menus) { $m['menu_name'] = $menu['pagetitle']; $m['menu_desc'] = $menu['desc']; if($menu['created']) - $m['menu_created'] = datetime_convert($menu['created']); + $m['menu_created'] = datetime_convert('UTC','UTC',$menu['created']); if($menu['edited']) - $m['menu_edited'] = datetime_convert($menu['edited']); + $m['menu_edited'] = datetime_convert('UTC','UTC',$menu['edited']); $m['menu_flags'] = 0; if($menu['flags']) { @@ -1345,6 +1346,7 @@ function sync_files($channel, $files) { logger('attachment store failed',LOGGER_NORMAL,LOG_ERR); } if($f['photo']) { + foreach($f['photo'] as $p) { unset($p['id']); $p['aid'] = $channel['channel_account_id']; @@ -1366,6 +1368,7 @@ function sync_files($channel, $files) { dbesc($p['resource_id']), intval($channel['channel_id']) ); + $update_xchan = $p['edited']; } // same for cover photos @@ -1385,19 +1388,20 @@ function sync_files($channel, $files) { else $p['content'] = (($p['content'])? base64_decode($p['content']) : ''); - if(intval($p['imgscale']) && (! $p['content'])) { + if(intval($p['imgscale']) && (! empty($p['content']))) { $time = datetime_convert(); - $parr = array('hash' => $channel['channel_hash'], + $parr = array( + 'hash' => $channel['channel_hash'], 'time' => $time, - 'resource' => $att['hash'], + 'resource' => $p['resource_id'], 'revision' => 0, 'signature' => base64url_encode(rsa_sign($channel['channel_hash'] . '.' . $time, $channel['channel_prvkey'])), - 'resolution' => $p['imgscale'] + 'resolution' => intval($p['imgscale']) ); - $stored_image = $newfname . '-' . intval($p['imgscale']); + $stored_image = $newfname . '-' . $p['imgscale']; $fp = fopen($stored_image,'w'); if(! $fp) { @@ -1406,7 +1410,6 @@ function sync_files($channel, $files) { } $redirects = 0; - $headers = []; $headers['Accept'] = 'application/x-zot+json' ; $headers['Sigtoken'] = random_string(); @@ -1414,8 +1417,17 @@ function sync_files($channel, $files) { $x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]); fclose($fp); - $p['content'] = file_get_contents($stored_image); - unlink($stored_image); + + // Override remote hub thumbnails storage settings + if(! boolval(get_config('system','filesystem_storage_thumbnails', 0))) { + $p['os_storage'] = 0; + $p['content'] = file_get_contents($stored_image); + @unlink($stored_image); + } + else { + $p['os_storage'] = 1; + $p['content'] = $stored_image; + } } if(!isset($p['display_path'])) @@ -1447,6 +1459,16 @@ function sync_files($channel, $files) { create_table_from_array('photo',$p, [ 'content' ] ); } } + + } + + // Set xchan photo date to prevent thumbnails fetch for clones on profile update packet recieve + if(isset($update_xchan)) { + + $x = q("UPDATE xchan SET xchan_photo_date = '%s' WHERE xchan_hash = '%s'", + dbescdate($update_xchan), + dbesc($channel['channel_hash']) + ); } \Zotlabs\Daemon\Master::Summon([ 'Thumbnail' , $att['hash'] ]); @@ -1621,12 +1643,12 @@ function import_webpage_element($element, $channel, $type) { $arr['created'] = $iteminfo[0]['created']; } else { // otherwise, generate the creation times and unique id - $arr['created'] = datetime_convert('UTC', 'UTC'); + $arr['created'] = datetime_convert(); $arr['uuid'] = item_message_id(); $arr['mid'] = $arr['parent_mid'] = z_root() . '/item/' . $arr['uuid']; } // Update the edited time whether or not the element already exists - $arr['edited'] = datetime_convert('UTC', 'UTC'); + $arr['edited'] = datetime_convert(); // Import the actual element content $arr['body'] = file_get_contents($element['path']); // The element owner is the channel importing the elements diff --git a/include/items.php b/include/items.php index c08deb3a0..95b696034 100755 --- a/include/items.php +++ b/include/items.php @@ -4278,7 +4278,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C if($arr['mid']) $sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' "; - $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) "; + $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE $item_uids and item_thread_top = 1 $sql_options $item_normal ) "; if($arr['since_id']) $sql_extra .= " and item.id > " . $since_id . " "; diff --git a/include/js_strings.php b/include/js_strings.php index c053e5666..f01fa87ae 100644 --- a/include/js_strings.php +++ b/include/js_strings.php @@ -33,6 +33,7 @@ function js_strings() { '$name_empty' => t('A channel name is required.'), '$name_ok1' => t('This is a '), '$name_ok2' => t(' channel name'), + '$to_reply' => t('Back to reply'), // translatable prefix and suffix strings for jquery.timeago - // using the defaults set below if left untranslated, empty strings if diff --git a/include/markdown.php b/include/markdown.php index 2513a7d77..7d1f16958 100644 --- a/include/markdown.php +++ b/include/markdown.php @@ -76,6 +76,8 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) { $s = html2bbcode($s); + $s = bb_code_protect($s); + // Convert everything that looks like a link to a link if($use_zrl) { if (strpos($s,'[/img]') !== false) { @@ -88,6 +90,8 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) { $s = preg_replace("/([^\]\=\{\/]|^)(https?\:\/\/)([a-zA-Z0-9\pL\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,\@\(\)]+)/ismu", '$1[url=$2$3]$2$3[/url]',$s); } + $s = bb_code_unprotect($s); + // remove duplicate adjacent code tags $s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s); diff --git a/include/oembed.php b/include/oembed.php index 426197c5f..ee9e57c3f 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -1,6 +1,6 @@ '', + 'title' => t('View PDF'), + 'type' => 'pdf' + ]; + // set $txt to something so that we don't attempt to fetch what could be a lengthy pdf. + $txt = EMPTY_STR; + } + if(is_null($txt)) { $txt = ""; @@ -215,20 +226,10 @@ function oembed_fetch_url($embedurl){ // save in cache if(! get_config('system','oembed_cache_disable')) - Zlib\Cache::set('[' . App::$videowidth . '] ' . $furl, $txt); + Cache::set('[' . App::$videowidth . '] ' . $furl, $txt); } - if(strpos(strtolower($embedurl),'.pdf') !== false) { - $action = 'allow'; - $j = [ - 'html' => '', - 'title' => t('View PDF'), - 'type' => 'pdf' - ]; - - } - if(! $j) { $j = json_decode($txt,true); } diff --git a/include/photos.php b/include/photos.php index 44406e0b0..7ea2729ae 100644 --- a/include/photos.php +++ b/include/photos.php @@ -277,8 +277,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 1024 || $height > 1024) && (! $errors)) $ph->scaleImage(1024); - $p['imgscale'] = 1; - $r1 = $ph->save($p); + $r1 = $ph->storeThumbnail($p, PHOTO_RES_1024); $link[1] = array( 'rel' => 'alternate', 'type' => 'text/html', @@ -292,8 +291,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 640 || $height > 640) && (! $errors)) $ph->scaleImage(640); - $p['imgscale'] = 2; - $r2 = $ph->save($p); + $r2 = $ph->storeThumbnail($p, PHOTO_RES_640); $link[2] = array( 'rel' => 'alternate', 'type' => 'text/html', @@ -307,8 +305,7 @@ function photo_upload($channel, $observer, $args) { if(($width > 320 || $height > 320) && (! $errors)) $ph->scaleImage(320); - $p['imgscale'] = 3; - $r3 = $ph->save($p); + $r3 = $ph->storeThumbnail($p, PHOTO_RES_320); $link[3] = array( 'rel' => 'alternate', 'type' => 'text/html', diff --git a/include/text.php b/include/text.php index e5a5ee98d..1e53e667b 100644 --- a/include/text.php +++ b/include/text.php @@ -409,7 +409,8 @@ function autoname($len) { * @return string Escaped text. */ function xmlify($str) { - $buffer = ''; + + //$buffer = ''; if(is_array($str)) { @@ -418,7 +419,7 @@ function xmlify($str) { btlogger('xmlify called with array: ' . print_r($str,true), LOGGER_NORMAL, LOG_WARNING); } - +/* $len = mb_strlen($str); for($x = 0; $x < $len; $x ++) { $char = mb_substr($str,$x,1); @@ -452,6 +453,11 @@ function xmlify($str) { $buffer = trim($buffer); return($buffer); +*/ + $buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8"); + $buffer = trim($buffer); + return $buffer; + } /** @@ -464,9 +470,22 @@ function xmlify($str) { * @return string */ function unxmlify($s) { +/* $ret = str_replace('&', '&', $s); $ret = str_replace(array('<', '>', '"', '''), array('<', '>', '"', "'"), $ret); + return $ret; +*/ + + if(is_array($s)) { + + // allow to fall through so we ge a PHP error, as the log statement will + // probably get lost in the noise unless we're specifically looking for it. + + btlogger('unxmlify called with array: ' . print_r($s,true), LOGGER_NORMAL, LOG_WARNING); + } + + $ret = htmlspecialchars_decode($s, ENT_QUOTES); return $ret; } @@ -3079,13 +3098,12 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') { if($oldnick) json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']); } + + $item['body'] = preg_replace("/(\[zrl=".preg_quote($old,'/')."\/(photo|photos|gallery)\/".$channel['channel_address'].".+\]\[zmg=\d+x\d+\])".preg_quote($old,'/')."\/(.+\[\/zmg\])/", '${1}'.$new.'/${3}', $item['body']); + $item['body'] = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']); - $x = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']); - if($x) { - $item['body'] = $x; - $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); - $item['item_verified'] = 1; - } + $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey'])); + $item['item_verified'] = 1; $item['plink'] = str_replace($old,$new,$item['plink']); if($oldnick) diff --git a/include/zot.php b/include/zot.php index 5ced4ee8c..a37b7cdb5 100644 --- a/include/zot.php +++ b/include/zot.php @@ -925,46 +925,62 @@ function import_xchan($arr, $ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) { $local = q("select channel_account_id, channel_id from channel where channel_hash = '%s' limit 1", dbesc($xchan_hash) ); + if($local) { + // @FIXME This should be removed in future when profile photo update by file sync procedure will be applied + // on most hubs in the network + // <--- $ph = z_fetch_url($arr['photo'], true); + if($ph['success']) { + + // Do not fetch already received thumbnails + $x = q("SELECT resource_id FROM photo WHERE uid = %d AND imgscale = %d AND filesize = %d LIMIT 1", + intval($local[0]['channel_id']), + intval(PHOTO_RES_PROFILE_300), + strlen($ph['body']) + ); - $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']); + if($x) + $hash = $x[0]['resource_id']; + else + $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']); + } + + if($hash) { + // unless proven otherwise + $is_default_profile = 1; - if($hash) { - // unless proven otherwise - $is_default_profile = 1; + $profile = q("select is_default from profile where aid = %d and uid = %d limit 1", + intval($local[0]['channel_account_id']), + intval($local[0]['channel_id']) + ); + if($profile) { + if(! intval($profile[0]['is_default'])) + $is_default_profile = 0; + } - $profile = q("select is_default from profile where aid = %d and uid = %d limit 1", + // If setting for the default profile, unset the profile photo flag from any other photos I own + if($is_default_profile) { + q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", + intval(PHOTO_NORMAL), + intval(PHOTO_PROFILE), + dbesc($hash), intval($local[0]['channel_account_id']), intval($local[0]['channel_id']) ); - if($profile) { - if(! intval($profile[0]['is_default'])) - $is_default_profile = 0; - } - - // If setting for the default profile, unset the profile photo flag from any other photos I own - if($is_default_profile) { - q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d", - intval(PHOTO_NORMAL), - intval(PHOTO_PROFILE), - dbesc($hash), - intval($local[0]['channel_account_id']), - intval($local[0]['channel_id']) - ); - } } - - // reset the names in case they got messed up when we had a bug in this function - $photos = array( - z_root() . '/photo/profile/l/' . $local[0]['channel_id'], - z_root() . '/photo/profile/m/' . $local[0]['channel_id'], - z_root() . '/photo/profile/s/' . $local[0]['channel_id'], - $arr['photo_mimetype'], - false - ); } + // ---> + + // reset the names in case they got messed up when we had a bug in this function + $photos = array( + z_root() . '/photo/profile/l/' . $local[0]['channel_id'], + z_root() . '/photo/profile/m/' . $local[0]['channel_id'], + z_root() . '/photo/profile/s/' . $local[0]['channel_id'], + $arr['photo_mimetype'], + false + ); } else { $photos = import_xchan_photo($arr['photo'], $xchan_hash); @@ -3634,7 +3650,7 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { 'channel_r_storage', 'channel_r_pages', 'channel_w_stream', 'channel_w_wall', 'channel_w_comment', 'channel_w_mail', 'channel_w_like', 'channel_w_tagwall', 'channel_w_chat', 'channel_w_storage', 'channel_w_pages', 'channel_a_republish', - 'channel_a_delegate', 'channel_moved' + 'channel_a_delegate', 'channel_moved', 'channel_r_photos', 'channel_w_photos' ]; $clean = array(); @@ -4414,7 +4430,7 @@ function zotinfo($arr) { $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; - if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],$e['channel_timezone'])) !== '')) + if(($profile['birthday'] != '0000-00-00') && (($bd = z_birthday($p[0]['dob'],'UTC')) !== '')) $profile['next_birthday'] = $bd; if($age = age($p[0]['dob'],$e['channel_timezone'],'')) diff --git a/install/INSTALL.txt b/install/INSTALL.txt index fe2484d7a..0503ae2cc 100644 --- a/install/INSTALL.txt +++ b/install/INSTALL.txt @@ -175,7 +175,7 @@ encounter a database configuration which cannot be expressed on the setup form (for instance using MySQL with an unusual socket location); you can supply the PDO connection string as the database hostname. For instance - mysql:unix_socket=/my/special/socket_path + :/path/to/socket.file You should still fill in all other applicable form values as needed. diff --git a/install/database-w-defaults-v1131.diff b/install/database-w-defaults-v1131.diff deleted file mode 100644 index c8870f9c4..000000000 --- a/install/database-w-defaults-v1131.diff +++ /dev/null @@ -1,1914 +0,0 @@ -*** database.sql Mon Sep 8 20:28:00 2014 ---- database-w-defaults.sql Sun Nov 9 19:20:32 2014 -*************** -*** 1,15 **** -! SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -! -! /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -! /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -! /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -! /*!40101 SET NAMES utf8 */; - - - CREATE TABLE IF NOT EXISTS `abook` ( - `abook_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `abook_account` int(10) unsigned NOT NULL, -! `abook_channel` int(10) unsigned NOT NULL, - `abook_xchan` char(255) NOT NULL DEFAULT '', - `abook_my_perms` int(11) NOT NULL DEFAULT '0', - `abook_their_perms` int(11) NOT NULL DEFAULT '0', ---- 1,13 ---- -! -- -------------------------------------------------------- - -+ -- -+ -- Table structure for table `abook` -+ -- - - CREATE TABLE IF NOT EXISTS `abook` ( - `abook_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `abook_account` int(10) unsigned NOT NULL DEFAULT '0', -! `abook_channel` int(10) unsigned NOT NULL DEFAULT '0', - `abook_xchan` char(255) NOT NULL DEFAULT '', - `abook_my_perms` int(11) NOT NULL DEFAULT '0', - `abook_their_perms` int(11) NOT NULL DEFAULT '0', -*************** -*** 37,42 **** ---- 35,46 ---- - KEY `abook_rating` (`abook_rating`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `account` -+ -- -+ - CREATE TABLE IF NOT EXISTS `account` ( - `account_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `account_parent` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 70,79 **** - KEY `account_password_changed` (`account_password_changed`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `addon` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `name` char(255) NOT NULL, -! `version` char(255) NOT NULL, - `installed` tinyint(1) NOT NULL DEFAULT '0', - `hidden` tinyint(1) NOT NULL DEFAULT '0', - `timestamp` bigint(20) NOT NULL DEFAULT '0', ---- 74,89 ---- - KEY `account_password_changed` (`account_password_changed`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `addon` -+ -- -+ - CREATE TABLE IF NOT EXISTS `addon` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `name` char(255) NOT NULL DEFAULT '', -! `version` char(255) NOT NULL DEFAULT '', - `installed` tinyint(1) NOT NULL DEFAULT '0', - `hidden` tinyint(1) NOT NULL DEFAULT '0', - `timestamp` bigint(20) NOT NULL DEFAULT '0', -*************** -*** 84,89 **** ---- 94,104 ---- - KEY `installed` (`installed`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `app` -+ -- - - CREATE TABLE IF NOT EXISTS `app` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -*************** -*** 108,115 **** - KEY `app_version` (`app_version`), - KEY `app_channel` (`app_channel`), - KEY `app_price` (`app_price`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - - CREATE TABLE IF NOT EXISTS `attach` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, ---- 123,135 ---- - KEY `app_version` (`app_version`), - KEY `app_channel` (`app_channel`), - KEY `app_price` (`app_price`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- - -+ -- -+ -- Table structure for table `attach` -+ -- - - CREATE TABLE IF NOT EXISTS `attach` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -*************** -*** 145,166 **** - KEY `creator` (`creator`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `auth_codes` ( -! `id` varchar(40) NOT NULL, -! `client_id` varchar(20) NOT NULL, -! `redirect_uri` varchar(200) NOT NULL, -! `expires` int(11) NOT NULL, -! `scope` varchar(250) NOT NULL, - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `cache` ( -! `k` char(255) NOT NULL, - `v` text NOT NULL, -! `updated` datetime NOT NULL, - PRIMARY KEY (`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `channel` ( - `channel_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `channel_account_id` int(10) unsigned NOT NULL DEFAULT '0', ---- 165,204 ---- - KEY `creator` (`creator`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `auth_codes` -+ -- -+ - CREATE TABLE IF NOT EXISTS `auth_codes` ( -! `id` varchar(40) NOT NULL DEFAULT '', -! `client_id` varchar(20) NOT NULL DEFAULT '', -! `redirect_uri` varchar(200) NOT NULL DEFAULT '', -! `expires` int(11) NOT NULL DEFAULT '0', -! `scope` varchar(250) NOT NULL DEFAULT '', - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `cache` -+ -- -+ - CREATE TABLE IF NOT EXISTS `cache` ( -! `k` char(255) NOT NULL DEFAULT '', - `v` text NOT NULL, -! `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `channel` -+ -- -+ - CREATE TABLE IF NOT EXISTS `channel` ( - `channel_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `channel_account_id` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 189,212 **** - `channel_allow_gid` mediumtext NOT NULL, - `channel_deny_cid` mediumtext NOT NULL, - `channel_deny_gid` mediumtext NOT NULL, -! `channel_r_stream` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_r_profile` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_r_photos` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_r_abook` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_stream` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_wall` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_tagwall` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_comment` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_mail` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_photos` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_chat` int(10) unsigned NOT NULL DEFAULT '128', - `channel_a_delegate` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_storage` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_storage` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_r_pages` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_pages` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_a_republish` int(10) unsigned NOT NULL DEFAULT '128', -! `channel_w_like` int(10) unsigned NOT NULL DEFAULT '128', - PRIMARY KEY (`channel_id`), - UNIQUE KEY `channel_address_unique` (`channel_address`), - KEY `channel_account_id` (`channel_account_id`), ---- 227,250 ---- - `channel_allow_gid` mediumtext NOT NULL, - `channel_deny_cid` mediumtext NOT NULL, - `channel_deny_gid` mediumtext NOT NULL, -! `channel_r_stream` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_profile` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_photos` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_abook` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_stream` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_wall` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_tagwall` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_comment` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_mail` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_photos` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_chat` int(10) unsigned NOT NULL DEFAULT '0', - `channel_a_delegate` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_storage` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_storage` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_r_pages` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_pages` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_a_republish` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_w_like` int(10) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`channel_id`), - UNIQUE KEY `channel_address_unique` (`channel_address`), - KEY `channel_account_id` (`channel_account_id`), -*************** -*** 241,250 **** - KEY `channel_w_pages` (`channel_w_pages`), - KEY `channel_deleted` (`channel_deleted`), - KEY `channel_a_republish` (`channel_a_republish`), -! KEY `channel_w_like` (`channel_w_like`), -! KEY `channel_dirdate` (`channel_dirdate`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `chat` ( - `chat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `chat_room` int(10) unsigned NOT NULL DEFAULT '0', ---- 279,294 ---- - KEY `channel_w_pages` (`channel_w_pages`), - KEY `channel_deleted` (`channel_deleted`), - KEY `channel_a_republish` (`channel_a_republish`), -! KEY `channel_dirdate` (`channel_dirdate`), -! KEY `channel_w_like` (`channel_w_like`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `chat` -+ -- -+ - CREATE TABLE IF NOT EXISTS `chat` ( - `chat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `chat_room` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 255,275 **** - KEY `chat_room` (`chat_room`), - KEY `chat_xchan` (`chat_xchan`), - KEY `created` (`created`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `chatpresence` ( - `cp_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `cp_room` int(10) unsigned NOT NULL DEFAULT '0', - `cp_xchan` char(255) NOT NULL DEFAULT '', - `cp_last` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `cp_status` char(255) NOT NULL, - `cp_client` char(128) NOT NULL DEFAULT '', - PRIMARY KEY (`cp_id`), - KEY `cp_room` (`cp_room`), - KEY `cp_xchan` (`cp_xchan`), - KEY `cp_last` (`cp_last`), - KEY `cp_status` (`cp_status`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `chatroom` ( - `cr_id` int(10) unsigned NOT NULL AUTO_INCREMENT, ---- 299,331 ---- - KEY `chat_room` (`chat_room`), - KEY `chat_xchan` (`chat_xchan`), - KEY `created` (`created`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `chatpresence` -! -- - - CREATE TABLE IF NOT EXISTS `chatpresence` ( - `cp_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `cp_room` int(10) unsigned NOT NULL DEFAULT '0', - `cp_xchan` char(255) NOT NULL DEFAULT '', - `cp_last` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `cp_status` char(255) NOT NULL DEFAULT '', - `cp_client` char(128) NOT NULL DEFAULT '', - PRIMARY KEY (`cp_id`), - KEY `cp_room` (`cp_room`), - KEY `cp_xchan` (`cp_xchan`), - KEY `cp_last` (`cp_last`), - KEY `cp_status` (`cp_status`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `chatroom` -! -- - - CREATE TABLE IF NOT EXISTS `chatroom` ( - `cr_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -*************** -*** 290,322 **** - KEY `cr_created` (`cr_created`), - KEY `cr_edited` (`cr_edited`), - KEY `cr_expire` (`cr_expire`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `clients` ( -! `client_id` varchar(20) NOT NULL, -! `pw` varchar(20) NOT NULL, -! `redirect_uri` varchar(200) NOT NULL, - `name` text, - `icon` text, - `uid` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`client_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `config` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `cat` char(255) CHARACTER SET ascii NOT NULL, -! `k` char(255) CHARACTER SET ascii NOT NULL, - `v` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `access` (`cat`,`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `conv` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `guid` char(255) NOT NULL, - `recips` mediumtext NOT NULL, -! `uid` int(11) NOT NULL, -! `creator` char(255) NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `subject` mediumtext NOT NULL, ---- 346,396 ---- - KEY `cr_created` (`cr_created`), - KEY `cr_edited` (`cr_edited`), - KEY `cr_expire` (`cr_expire`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `clients` -! -- - - CREATE TABLE IF NOT EXISTS `clients` ( -! `client_id` varchar(20) NOT NULL DEFAULT '', -! `pw` varchar(20) NOT NULL DEFAULT '', -! `redirect_uri` varchar(200) NOT NULL DEFAULT '', - `name` text, - `icon` text, - `uid` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`client_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `config` -+ -- -+ - CREATE TABLE IF NOT EXISTS `config` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `cat` char(255) CHARACTER SET ascii NOT NULL DEFAULT '', -! `k` char(255) CHARACTER SET ascii NOT NULL DEFAULT '', - `v` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `access` (`cat`,`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `conv` -+ -- -+ - CREATE TABLE IF NOT EXISTS `conv` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `guid` char(255) NOT NULL DEFAULT '', - `recips` mediumtext NOT NULL, -! `uid` int(11) NOT NULL DEFAULT '0', -! `creator` char(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `subject` mediumtext NOT NULL, -*************** -*** 325,344 **** - KEY `updated` (`updated`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `event` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL, - `event_xchan` char(255) NOT NULL DEFAULT '', - `event_hash` char(255) NOT NULL DEFAULT '', -! `created` datetime NOT NULL, -! `edited` datetime NOT NULL, -! `start` datetime NOT NULL, -! `finish` datetime NOT NULL, - `summary` text NOT NULL, - `description` text NOT NULL, - `location` text NOT NULL, -! `type` char(255) NOT NULL, - `nofinish` tinyint(1) NOT NULL DEFAULT '0', - `adjust` tinyint(1) NOT NULL DEFAULT '1', - `ignore` tinyint(1) NOT NULL DEFAULT '0', ---- 399,424 ---- - KEY `updated` (`updated`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `event` -+ -- -+ - CREATE TABLE IF NOT EXISTS `event` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL DEFAULT '0', - `event_xchan` char(255) NOT NULL DEFAULT '', - `event_hash` char(255) NOT NULL DEFAULT '', -! `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `start` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `finish` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `summary` text NOT NULL, - `description` text NOT NULL, - `location` text NOT NULL, -! `type` char(255) NOT NULL DEFAULT '', - `nofinish` tinyint(1) NOT NULL DEFAULT '0', - `adjust` tinyint(1) NOT NULL DEFAULT '1', - `ignore` tinyint(1) NOT NULL DEFAULT '0', -*************** -*** 357,363 **** - KEY `aid` (`aid`), - KEY `event_hash` (`event_hash`), - KEY `event_xchan` (`event_xchan`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `fcontact` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, ---- 437,449 ---- - KEY `aid` (`aid`), - KEY `event_hash` (`event_hash`), - KEY `event_xchan` (`event_xchan`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `fcontact` -! -- - - CREATE TABLE IF NOT EXISTS `fcontact` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -*************** -*** 381,386 **** ---- 467,478 ---- - KEY `network` (`network`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `ffinder` -+ -- -+ - CREATE TABLE IF NOT EXISTS `ffinder` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `uid` int(10) unsigned NOT NULL, -*************** -*** 392,427 **** - KEY `fid` (`fid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `fserver` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `server` char(255) NOT NULL, -! `posturl` char(255) NOT NULL, - `key` text NOT NULL, - PRIMARY KEY (`id`), - KEY `server` (`server`), - KEY `posturl` (`posturl`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `fsuggest` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL, -! `cid` int(11) NOT NULL, -! `name` char(255) NOT NULL, -! `url` char(255) NOT NULL, -! `request` char(255) NOT NULL, -! `photo` char(255) NOT NULL, - `note` text NOT NULL, -! `created` datetime NOT NULL, - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `groups` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `hash` char(255) NOT NULL DEFAULT '', -! `uid` int(10) unsigned NOT NULL, - `visible` tinyint(1) NOT NULL DEFAULT '0', - `deleted` tinyint(1) NOT NULL DEFAULT '0', -! `name` char(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `visible` (`visible`), ---- 484,537 ---- - KEY `fid` (`fid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `fserver` -+ -- -+ - CREATE TABLE IF NOT EXISTS `fserver` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `server` char(255) NOT NULL DEFAULT '', -! `posturl` char(255) NOT NULL DEFAULT '', - `key` text NOT NULL, - PRIMARY KEY (`id`), - KEY `server` (`server`), - KEY `posturl` (`posturl`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `fsuggest` -+ -- -+ - CREATE TABLE IF NOT EXISTS `fsuggest` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL DEFAULT '0', -! `cid` int(11) NOT NULL DEFAULT '0', -! `name` char(255) NOT NULL DEFAULT '', -! `url` char(255) NOT NULL DEFAULT '', -! `request` char(255) NOT NULL DEFAULT '', -! `photo` char(255) NOT NULL DEFAULT '', - `note` text NOT NULL, -! `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `groups` -+ -- -+ - CREATE TABLE IF NOT EXISTS `groups` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `hash` char(255) NOT NULL DEFAULT '', -! `uid` int(10) unsigned NOT NULL DEFAULT '0', - `visible` tinyint(1) NOT NULL DEFAULT '0', - `deleted` tinyint(1) NOT NULL DEFAULT '0', -! `name` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `visible` (`visible`), -*************** -*** 429,438 **** - KEY `hash` (`hash`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `group_member` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `uid` int(10) unsigned NOT NULL, -! `gid` int(10) unsigned NOT NULL, - `xchan` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), ---- 539,554 ---- - KEY `hash` (`hash`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `group_member` -+ -- -+ - CREATE TABLE IF NOT EXISTS `group_member` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `uid` int(10) unsigned NOT NULL DEFAULT '0', -! `gid` int(10) unsigned NOT NULL DEFAULT '0', - `xchan` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), -*************** -*** 440,460 **** - KEY `xchan` (`xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `hook` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `hook` char(255) NOT NULL, -! `file` char(255) NOT NULL, -! `function` char(255) NOT NULL, - `priority` int(11) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `hook` (`hook`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `hubloc` ( - `hubloc_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `hubloc_guid` char(255) NOT NULL DEFAULT '', - `hubloc_guid_sig` text NOT NULL, -! `hubloc_hash` char(255) NOT NULL, - `hubloc_addr` char(255) NOT NULL DEFAULT '', - `hubloc_network` char(32) NOT NULL DEFAULT '', - `hubloc_flags` int(10) unsigned NOT NULL DEFAULT '0', ---- 556,588 ---- - KEY `xchan` (`xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `hook` -+ -- -+ - CREATE TABLE IF NOT EXISTS `hook` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `hook` char(255) NOT NULL DEFAULT '', -! `file` char(255) NOT NULL DEFAULT '', -! `function` char(255) NOT NULL DEFAULT '', - `priority` int(11) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `hook` (`hook`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `hubloc` -+ -- -+ - CREATE TABLE IF NOT EXISTS `hubloc` ( - `hubloc_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `hubloc_guid` char(255) NOT NULL DEFAULT '', - `hubloc_guid_sig` text NOT NULL, -! `hubloc_hash` char(255) NOT NULL DEFAULT '', - `hubloc_addr` char(255) NOT NULL DEFAULT '', - `hubloc_network` char(32) NOT NULL DEFAULT '', - `hubloc_flags` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 474,493 **** - KEY `hubloc_connect` (`hubloc_connect`), - KEY `hubloc_host` (`hubloc_host`), - KEY `hubloc_addr` (`hubloc_addr`), -- KEY `hubloc_network` (`hubloc_network`), - KEY `hubloc_updated` (`hubloc_updated`), - KEY `hubloc_connected` (`hubloc_connected`), -! KEY `hubloc_status` (`hubloc_status`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `issue` ( - `issue_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `issue_created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `issue_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `issue_assigned` char(255) NOT NULL, -! `issue_priority` int(11) NOT NULL, -! `issue_status` int(11) NOT NULL, -! `issue_component` char(255) NOT NULL, - PRIMARY KEY (`issue_id`), - KEY `issue_created` (`issue_created`), - KEY `issue_updated` (`issue_updated`), ---- 602,627 ---- - KEY `hubloc_connect` (`hubloc_connect`), - KEY `hubloc_host` (`hubloc_host`), - KEY `hubloc_addr` (`hubloc_addr`), - KEY `hubloc_updated` (`hubloc_updated`), - KEY `hubloc_connected` (`hubloc_connected`), -! KEY `hubloc_status` (`hubloc_status`), -! KEY `hubloc_network` (`hubloc_network`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `issue` -+ -- -+ - CREATE TABLE IF NOT EXISTS `issue` ( - `issue_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `issue_created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `issue_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `issue_assigned` char(255) NOT NULL DEFAULT '', -! `issue_priority` int(11) NOT NULL DEFAULT '0', -! `issue_status` int(11) NOT NULL DEFAULT '0', -! `issue_component` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`issue_id`), - KEY `issue_created` (`issue_created`), - KEY `issue_updated` (`issue_updated`), -*************** -*** 497,502 **** ---- 631,642 ---- - KEY `issue_component` (`issue_component`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `item` -+ -- -+ - CREATE TABLE IF NOT EXISTS `item` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `mid` char(255) CHARACTER SET ascii NOT NULL DEFAULT '', -*************** -*** 516,549 **** - `author_xchan` char(255) NOT NULL DEFAULT '', - `source_xchan` char(255) NOT NULL DEFAULT '', - `mimetype` char(255) NOT NULL DEFAULT '', -! `title` text NOT NULL DEFAULT '', -! `body` mediumtext NOT NULL DEFAULT '', - `app` char(255) NOT NULL DEFAULT '', - `lang` char(64) NOT NULL DEFAULT '', - `revision` int(10) unsigned NOT NULL DEFAULT '0', - `verb` char(255) NOT NULL DEFAULT '', - `obj_type` char(255) NOT NULL DEFAULT '', -! `object` text NOT NULL DEFAULT '', - `tgt_type` char(255) NOT NULL DEFAULT '', -! `target` text NOT NULL DEFAULT '', - `layout_mid` char(255) NOT NULL DEFAULT '', -! `postopts` text NOT NULL DEFAULT '', -! `route` text NOT NULL DEFAULT '', - `llink` char(255) NOT NULL DEFAULT '', - `plink` char(255) NOT NULL DEFAULT '', - `resource_id` char(255) NOT NULL DEFAULT '', - `resource_type` char(16) NOT NULL DEFAULT '', -! `attach` mediumtext NOT NULL DEFAULT '', -! `sig` text NOT NULL DEFAULT '', -! `diaspora_meta` mediumtext NOT NULL DEFAULT '', - `location` char(255) NOT NULL DEFAULT '', - `coord` char(255) NOT NULL DEFAULT '', - `public_policy` char(255) NOT NULL DEFAULT '', - `comment_policy` char(255) NOT NULL DEFAULT '', -! `allow_cid` mediumtext NOT NULL DEFAULT '', -! `allow_gid` mediumtext NOT NULL DEFAULT '', -! `deny_cid` mediumtext NOT NULL DEFAULT '', -! `deny_gid` mediumtext NOT NULL DEFAULT '', - `item_restrict` int(11) NOT NULL DEFAULT '0', - `item_flags` int(11) NOT NULL DEFAULT '0', - `item_private` tinyint(4) NOT NULL DEFAULT '0', ---- 656,689 ---- - `author_xchan` char(255) NOT NULL DEFAULT '', - `source_xchan` char(255) NOT NULL DEFAULT '', - `mimetype` char(255) NOT NULL DEFAULT '', -! `title` text NOT NULL, -! `body` mediumtext NOT NULL, - `app` char(255) NOT NULL DEFAULT '', - `lang` char(64) NOT NULL DEFAULT '', - `revision` int(10) unsigned NOT NULL DEFAULT '0', - `verb` char(255) NOT NULL DEFAULT '', - `obj_type` char(255) NOT NULL DEFAULT '', -! `object` text NOT NULL, - `tgt_type` char(255) NOT NULL DEFAULT '', -! `target` text NOT NULL, - `layout_mid` char(255) NOT NULL DEFAULT '', -! `postopts` text NOT NULL, -! `route` text NOT NULL, - `llink` char(255) NOT NULL DEFAULT '', - `plink` char(255) NOT NULL DEFAULT '', - `resource_id` char(255) NOT NULL DEFAULT '', - `resource_type` char(16) NOT NULL DEFAULT '', -! `attach` mediumtext NOT NULL, -! `sig` text NOT NULL, -! `diaspora_meta` mediumtext NOT NULL, - `location` char(255) NOT NULL DEFAULT '', - `coord` char(255) NOT NULL DEFAULT '', - `public_policy` char(255) NOT NULL DEFAULT '', - `comment_policy` char(255) NOT NULL DEFAULT '', -! `allow_cid` mediumtext NOT NULL, -! `allow_gid` mediumtext NOT NULL, -! `deny_cid` mediumtext NOT NULL, -! `deny_gid` mediumtext NOT NULL, - `item_restrict` int(11) NOT NULL DEFAULT '0', - `item_flags` int(11) NOT NULL DEFAULT '0', - `item_private` tinyint(4) NOT NULL DEFAULT '0', -*************** -*** 555,562 **** - KEY `received` (`received`), - KEY `uid_commented` (`uid`,`commented`), - KEY `uid_created` (`uid`,`created`), -- KEY `changed` (`changed`), -- KEY `comments_closed` (`comments_closed`), - KEY `aid` (`aid`), - KEY `owner_xchan` (`owner_xchan`), - KEY `author_xchan` (`author_xchan`), ---- 695,700 ---- -*************** -*** 573,581 **** - KEY `mid` (`mid`), - KEY `parent_mid` (`parent_mid`), - KEY `uid_mid` (`mid`,`uid`), -- KEY `public_policy` (`public_policy`), - KEY `comment_policy` (`comment_policy`), - KEY `layout_mid` (`layout_mid`), - FULLTEXT KEY `title` (`title`), - FULLTEXT KEY `body` (`body`), - FULLTEXT KEY `allow_cid` (`allow_cid`), ---- 711,721 ---- - KEY `mid` (`mid`), - KEY `parent_mid` (`parent_mid`), - KEY `uid_mid` (`mid`,`uid`), - KEY `comment_policy` (`comment_policy`), - KEY `layout_mid` (`layout_mid`), -+ KEY `public_policy` (`public_policy`), -+ KEY `comments_closed` (`comments_closed`), -+ KEY `changed` (`changed`), - FULLTEXT KEY `title` (`title`), - FULLTEXT KEY `body` (`body`), - FULLTEXT KEY `allow_cid` (`allow_cid`), -*************** -*** 584,595 **** - FULLTEXT KEY `deny_gid` (`deny_gid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `item_id` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `iid` int(11) NOT NULL, -! `uid` int(11) NOT NULL, -! `sid` char(255) NOT NULL, -! `service` char(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `sid` (`sid`), ---- 724,741 ---- - FULLTEXT KEY `deny_gid` (`deny_gid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `item_id` -+ -- -+ - CREATE TABLE IF NOT EXISTS `item_id` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `iid` int(11) NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL DEFAULT '0', -! `sid` char(255) NOT NULL DEFAULT '', -! `service` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `sid` (`sid`), -*************** -*** 597,621 **** - KEY `iid` (`iid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `likes` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `channel_id` int(11) unsigned NOT NULL DEFAULT '0', - `liker` char(128) NOT NULL DEFAULT '', - `likee` char(128) NOT NULL DEFAULT '', -! `iid` int(10) unsigned NOT NULL DEFAULT '0', - `verb` char(255) NOT NULL DEFAULT '', - `target_type` char(255) NOT NULL DEFAULT '', - `target_id` char(128) NOT NULL DEFAULT '', - `target` mediumtext NOT NULL, - PRIMARY KEY (`id`), -- KEY `channel_id` (`channel_id`), - KEY `liker` (`liker`), - KEY `likee` (`likee`), - KEY `iid` (`iid`), - KEY `verb` (`verb`), - KEY `target_type` (`target_type`), - KEY `target_id` (`target_id`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `mail` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, ---- 743,779 ---- - KEY `iid` (`iid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `likes` -+ -- -+ - CREATE TABLE IF NOT EXISTS `likes` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `channel_id` int(10) unsigned NOT NULL DEFAULT '0', - `liker` char(128) NOT NULL DEFAULT '', - `likee` char(128) NOT NULL DEFAULT '', -! `iid` int(11) unsigned NOT NULL DEFAULT '0', - `verb` char(255) NOT NULL DEFAULT '', - `target_type` char(255) NOT NULL DEFAULT '', - `target_id` char(128) NOT NULL DEFAULT '', - `target` mediumtext NOT NULL, - PRIMARY KEY (`id`), - KEY `liker` (`liker`), - KEY `likee` (`likee`), - KEY `iid` (`iid`), - KEY `verb` (`verb`), - KEY `target_type` (`target_type`), -+ KEY `channel_id` (`channel_id`), - KEY `target_id` (`target_id`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `mail` -! -- - - CREATE TABLE IF NOT EXISTS `mail` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -*************** -*** 624,639 **** - `from_xchan` char(255) NOT NULL DEFAULT '', - `to_xchan` char(255) NOT NULL DEFAULT '', - `account_id` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_id` int(10) unsigned NOT NULL, - `title` text NOT NULL, - `body` mediumtext NOT NULL, - `attach` mediumtext NOT NULL, -! `mid` char(255) NOT NULL, -! `parent_mid` char(255) NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`), -- KEY `convid` (`convid`), - KEY `created` (`created`), - KEY `mail_flags` (`mail_flags`), - KEY `account_id` (`account_id`), ---- 782,796 ---- - `from_xchan` char(255) NOT NULL DEFAULT '', - `to_xchan` char(255) NOT NULL DEFAULT '', - `account_id` int(10) unsigned NOT NULL DEFAULT '0', -! `channel_id` int(10) unsigned NOT NULL DEFAULT '0', - `title` text NOT NULL, - `body` mediumtext NOT NULL, - `attach` mediumtext NOT NULL, -! `mid` char(255) NOT NULL DEFAULT '', -! `parent_mid` char(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`), - KEY `created` (`created`), - KEY `mail_flags` (`mail_flags`), - KEY `account_id` (`account_id`), -*************** -*** 642,659 **** - KEY `to_xchan` (`to_xchan`), - KEY `mid` (`mid`), - KEY `parent_mid` (`parent_mid`), -! KEY `expires` (`expires`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `manage` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL, - `xchan` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `xchan` (`xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `menu` ( - `menu_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `menu_channel_id` int(10) unsigned NOT NULL DEFAULT '0', ---- 799,829 ---- - KEY `to_xchan` (`to_xchan`), - KEY `mid` (`mid`), - KEY `parent_mid` (`parent_mid`), -! KEY `expires` (`expires`), -! KEY `convid` (`convid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `manage` -+ -- -+ - CREATE TABLE IF NOT EXISTS `manage` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL DEFAULT '0', - `xchan` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `xchan` (`xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `menu` -+ -- -+ - CREATE TABLE IF NOT EXISTS `menu` ( - `menu_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `menu_channel_id` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 666,671 **** ---- 836,847 ---- - KEY `menu_flags` (`menu_flags`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `menu_item` -+ -- -+ - CREATE TABLE IF NOT EXISTS `menu_item` ( - `mitem_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `mitem_link` char(255) NOT NULL DEFAULT '', -*************** -*** 675,681 **** - `allow_gid` mediumtext NOT NULL, - `deny_cid` mediumtext NOT NULL, - `deny_gid` mediumtext NOT NULL, -! `mitem_channel_id` int(10) unsigned NOT NULL, - `mitem_menu_id` int(10) unsigned NOT NULL DEFAULT '0', - `mitem_order` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`mitem_id`), ---- 851,857 ---- - `allow_gid` mediumtext NOT NULL, - `deny_cid` mediumtext NOT NULL, - `deny_gid` mediumtext NOT NULL, -! `mitem_channel_id` int(10) unsigned NOT NULL DEFAULT '0', - `mitem_menu_id` int(10) unsigned NOT NULL DEFAULT '0', - `mitem_order` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`mitem_id`), -*************** -*** 684,705 **** - KEY `mitem_flags` (`mitem_flags`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `notify` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `hash` char(64) NOT NULL, -! `name` char(255) NOT NULL, -! `url` char(255) NOT NULL, -! `photo` char(255) NOT NULL, -! `date` datetime NOT NULL, - `msg` mediumtext NOT NULL, -! `aid` int(11) NOT NULL, -! `uid` int(11) NOT NULL, -! `link` char(255) NOT NULL, - `parent` char(255) NOT NULL DEFAULT '', - `seen` tinyint(1) NOT NULL DEFAULT '0', -! `type` int(11) NOT NULL, -! `verb` char(255) NOT NULL, -! `otype` char(16) NOT NULL, - PRIMARY KEY (`id`), - KEY `type` (`type`), - KEY `seen` (`seen`), ---- 860,887 ---- - KEY `mitem_flags` (`mitem_flags`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `notify` -+ -- -+ - CREATE TABLE IF NOT EXISTS `notify` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `hash` char(64) NOT NULL DEFAULT '', -! `name` char(255) NOT NULL DEFAULT '', -! `url` char(255) NOT NULL DEFAULT '', -! `photo` char(255) NOT NULL DEFAULT '', -! `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `msg` mediumtext NOT NULL, -! `aid` int(11) NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL DEFAULT '0', -! `link` char(255) NOT NULL DEFAULT '', - `parent` char(255) NOT NULL DEFAULT '', - `seen` tinyint(1) NOT NULL DEFAULT '0', -! `type` int(11) NOT NULL DEFAULT '0', -! `verb` char(255) NOT NULL DEFAULT '', -! `otype` char(16) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `type` (`type`), - KEY `seen` (`seen`), -*************** -*** 712,717 **** ---- 894,905 ---- - KEY `aid` (`aid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `obj` -+ -- -+ - CREATE TABLE IF NOT EXISTS `obj` ( - `obj_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `obj_page` char(64) NOT NULL DEFAULT '', -*************** -*** 731,736 **** ---- 919,930 ---- - KEY `obj_obj` (`obj_obj`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `outq` -+ -- -+ - CREATE TABLE IF NOT EXISTS `outq` ( - `outq_hash` char(255) NOT NULL, - `outq_account` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 753,786 **** - KEY `outq_delivered` (`outq_delivered`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `pconfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `uid` int(11) NOT NULL DEFAULT '0', -! `cat` char(255) CHARACTER SET ascii NOT NULL, -! `k` char(255) CHARACTER SET ascii NOT NULL, - `v` mediumtext NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `access` (`uid`,`cat`,`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `photo` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(10) unsigned NOT NULL, - `xchan` char(255) NOT NULL DEFAULT '', -! `resource_id` char(255) NOT NULL, -! `created` datetime NOT NULL, -! `edited` datetime NOT NULL, -! `title` char(255) NOT NULL, - `description` text NOT NULL, -! `album` char(255) NOT NULL, -! `filename` char(255) NOT NULL, - `type` char(128) NOT NULL DEFAULT 'image/jpeg', -! `height` smallint(6) NOT NULL, -! `width` smallint(6) NOT NULL, - `size` int(10) unsigned NOT NULL DEFAULT '0', - `data` mediumblob NOT NULL, -! `scale` tinyint(3) NOT NULL, - `profile` tinyint(1) NOT NULL DEFAULT '0', - `photo_flags` int(10) unsigned NOT NULL DEFAULT '0', - `allow_cid` mediumtext NOT NULL, ---- 947,992 ---- - KEY `outq_delivered` (`outq_delivered`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `pconfig` -+ -- -+ - CREATE TABLE IF NOT EXISTS `pconfig` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `uid` int(11) NOT NULL DEFAULT '0', -! `cat` char(255) CHARACTER SET ascii NOT NULL DEFAULT '', -! `k` char(255) CHARACTER SET ascii NOT NULL DEFAULT '', - `v` mediumtext NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `access` (`uid`,`cat`,`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `photo` -+ -- -+ - CREATE TABLE IF NOT EXISTS `photo` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(10) unsigned NOT NULL DEFAULT '0', - `xchan` char(255) NOT NULL DEFAULT '', -! `resource_id` char(255) NOT NULL DEFAULT '', -! `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `title` char(255) NOT NULL DEFAULT '', - `description` text NOT NULL, -! `album` char(255) NOT NULL DEFAULT '', -! `filename` char(255) NOT NULL DEFAULT '', - `type` char(128) NOT NULL DEFAULT 'image/jpeg', -! `height` smallint(6) NOT NULL DEFAULT '0', -! `width` smallint(6) NOT NULL DEFAULT '0', - `size` int(10) unsigned NOT NULL DEFAULT '0', - `data` mediumblob NOT NULL, -! `scale` tinyint(3) NOT NULL DEFAULT '0', - `profile` tinyint(1) NOT NULL DEFAULT '0', - `photo_flags` int(10) unsigned NOT NULL DEFAULT '0', - `allow_cid` mediumtext NOT NULL, -*************** -*** 800,805 **** ---- 1006,1017 ---- - KEY `resource_id` (`resource_id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `poll` -+ -- -+ - CREATE TABLE IF NOT EXISTS `poll` ( - `poll_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `poll_channel` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 812,817 **** ---- 1024,1035 ---- - KEY `poll_votes` (`poll_votes`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `poll_elm` -+ -- -+ - CREATE TABLE IF NOT EXISTS `poll_elm` ( - `pelm_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `pelm_poll` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 823,838 **** - KEY `pelm_result` (`pelm_result`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `profdef` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `field_name` char(255) NOT NULL DEFAULT '', - `field_type` char(16) NOT NULL DEFAULT '', - `field_desc` char(255) NOT NULL DEFAULT '', - `field_help` char(255) NOT NULL DEFAULT '', -! `field_inputs` mediumtext NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `field_name` (`field_name`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `profext` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, ---- 1041,1068 ---- - KEY `pelm_result` (`pelm_result`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `profdef` -+ -- -+ - CREATE TABLE IF NOT EXISTS `profdef` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `field_name` char(255) NOT NULL DEFAULT '', - `field_type` char(16) NOT NULL DEFAULT '', - `field_desc` char(255) NOT NULL DEFAULT '', - `field_help` char(255) NOT NULL DEFAULT '', -! `field_inputs` mediumtext NOT NULL, - PRIMARY KEY (`id`), - KEY `field_name` (`field_name`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `profext` -! -- - - CREATE TABLE IF NOT EXISTS `profext` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -*************** -*** 844,882 **** - KEY `channel_id` (`channel_id`), - KEY `hash` (`hash`), - KEY `k` (`k`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `profile` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `profile_guid` char(64) NOT NULL DEFAULT '', - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL, -! `profile_name` char(255) NOT NULL, - `is_default` tinyint(1) NOT NULL DEFAULT '0', - `hide_friends` tinyint(1) NOT NULL DEFAULT '0', -! `name` char(255) NOT NULL, -! `pdesc` char(255) NOT NULL, - `chandesc` text NOT NULL, - `dob` char(32) NOT NULL DEFAULT '0000-00-00', - `dob_tz` char(255) NOT NULL DEFAULT 'UTC', -! `address` char(255) NOT NULL, -! `locality` char(255) NOT NULL, -! `region` char(255) NOT NULL, -! `postal_code` char(32) NOT NULL, -! `country_name` char(255) NOT NULL, -! `hometown` char(255) NOT NULL, -! `gender` char(32) NOT NULL, -! `marital` char(255) NOT NULL, - `with` text NOT NULL, - `howlong` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `sexual` char(255) NOT NULL, -! `politic` char(255) NOT NULL, -! `religion` char(255) NOT NULL, - `keywords` text NOT NULL, - `likes` text NOT NULL, - `dislikes` text NOT NULL, - `about` text NOT NULL, -! `summary` char(255) NOT NULL, - `music` text NOT NULL, - `book` text NOT NULL, - `tv` text NOT NULL, ---- 1074,1118 ---- - KEY `channel_id` (`channel_id`), - KEY `hash` (`hash`), - KEY `k` (`k`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `profile` -! -- - - CREATE TABLE IF NOT EXISTS `profile` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `profile_guid` char(64) NOT NULL DEFAULT '', - `aid` int(10) unsigned NOT NULL DEFAULT '0', -! `uid` int(11) NOT NULL DEFAULT '0', -! `profile_name` char(255) NOT NULL DEFAULT '', - `is_default` tinyint(1) NOT NULL DEFAULT '0', - `hide_friends` tinyint(1) NOT NULL DEFAULT '0', -! `name` char(255) NOT NULL DEFAULT '', -! `pdesc` char(255) NOT NULL DEFAULT '', - `chandesc` text NOT NULL, - `dob` char(32) NOT NULL DEFAULT '0000-00-00', - `dob_tz` char(255) NOT NULL DEFAULT 'UTC', -! `address` char(255) NOT NULL DEFAULT '', -! `locality` char(255) NOT NULL DEFAULT '', -! `region` char(255) NOT NULL DEFAULT '', -! `postal_code` char(32) NOT NULL DEFAULT '', -! `country_name` char(255) NOT NULL DEFAULT '', -! `hometown` char(255) NOT NULL DEFAULT '', -! `gender` char(32) NOT NULL DEFAULT '', -! `marital` char(255) NOT NULL DEFAULT '', - `with` text NOT NULL, - `howlong` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `sexual` char(255) NOT NULL DEFAULT '', -! `politic` char(255) NOT NULL DEFAULT '', -! `religion` char(255) NOT NULL DEFAULT '', - `keywords` text NOT NULL, - `likes` text NOT NULL, - `dislikes` text NOT NULL, - `about` text NOT NULL, -! `summary` char(255) NOT NULL DEFAULT '', - `music` text NOT NULL, - `book` text NOT NULL, - `tv` text NOT NULL, -*************** -*** 887,895 **** - `education` text NOT NULL, - `contact` text NOT NULL, - `channels` text NOT NULL, -! `homepage` char(255) NOT NULL, -! `photo` char(255) NOT NULL, -! `thumb` char(255) NOT NULL, - `publish` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `guid` (`profile_guid`,`uid`), ---- 1123,1131 ---- - `education` text NOT NULL, - `contact` text NOT NULL, - `channels` text NOT NULL, -! `homepage` char(255) NOT NULL DEFAULT '', -! `photo` char(255) NOT NULL DEFAULT '', -! `thumb` char(255) NOT NULL DEFAULT '', - `publish` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `guid` (`profile_guid`,`uid`), -*************** -*** 908,920 **** - KEY `profile_guid` (`profile_guid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `profile_check` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `uid` int(10) unsigned NOT NULL, - `cid` int(10) unsigned NOT NULL DEFAULT '0', -! `dfrn_id` char(255) NOT NULL, -! `sec` char(255) NOT NULL, -! `expire` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `cid` (`cid`), ---- 1144,1162 ---- - KEY `profile_guid` (`profile_guid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `profile_check` -+ -- -+ - CREATE TABLE IF NOT EXISTS `profile_check` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `uid` int(10) unsigned NOT NULL DEFAULT '0', - `cid` int(10) unsigned NOT NULL DEFAULT '0', -! `dfrn_id` char(255) NOT NULL DEFAULT '', -! `sec` char(255) NOT NULL DEFAULT '', -! `expire` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), - KEY `cid` (`cid`), -*************** -*** 923,951 **** - KEY `expire` (`expire`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `register` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `hash` char(255) NOT NULL, -! `created` datetime NOT NULL, -! `uid` int(10) unsigned NOT NULL, -! `password` char(255) NOT NULL, -! `language` char(16) NOT NULL, - PRIMARY KEY (`id`), - KEY `hash` (`hash`), - KEY `created` (`created`), - KEY `uid` (`uid`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `session` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, -! `sid` char(255) NOT NULL, - `data` text NOT NULL, -! `expire` bigint(20) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `sid` (`sid`), - KEY `expire` (`expire`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `shares` ( - `share_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `share_type` int(11) NOT NULL DEFAULT '0', ---- 1165,1211 ---- - KEY `expire` (`expire`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `register` -+ -- -+ - CREATE TABLE IF NOT EXISTS `register` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `hash` char(255) NOT NULL DEFAULT '', -! `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -! `uid` int(10) unsigned NOT NULL DEFAULT '0', -! `password` char(255) NOT NULL DEFAULT '', -! `language` char(16) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `hash` (`hash`), - KEY `created` (`created`), - KEY `uid` (`uid`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `session` -! -- - - CREATE TABLE IF NOT EXISTS `session` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, -! `sid` char(255) NOT NULL DEFAULT '', - `data` text NOT NULL, -! `expire` bigint(20) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `sid` (`sid`), - KEY `expire` (`expire`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `shares` -+ -- -+ - CREATE TABLE IF NOT EXISTS `shares` ( - `share_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `share_type` int(11) NOT NULL DEFAULT '0', -*************** -*** 957,974 **** - KEY `share_xchan` (`share_xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `sign` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `iid` int(10) unsigned NOT NULL DEFAULT '0', - `retract_iid` int(10) unsigned NOT NULL DEFAULT '0', - `signed_text` mediumtext NOT NULL, - `signature` text NOT NULL, -! `signer` char(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `iid` (`iid`), - KEY `retract_iid` (`retract_iid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `site` ( - `site_url` char(255) NOT NULL, - `site_access` int(11) NOT NULL DEFAULT '0', ---- 1217,1246 ---- - KEY `share_xchan` (`share_xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `sign` -+ -- -+ - CREATE TABLE IF NOT EXISTS `sign` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `iid` int(10) unsigned NOT NULL DEFAULT '0', - `retract_iid` int(10) unsigned NOT NULL DEFAULT '0', - `signed_text` mediumtext NOT NULL, - `signature` text NOT NULL, -! `signer` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`id`), - KEY `iid` (`iid`), - KEY `retract_iid` (`retract_iid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `site` -+ -- -+ - CREATE TABLE IF NOT EXISTS `site` ( - `site_url` char(255) NOT NULL, - `site_access` int(11) NOT NULL DEFAULT '0', -*************** -*** 988,996 **** ---- 1260,1275 ---- - KEY `site_register` (`site_register`), - KEY `site_access` (`site_access`), - KEY `site_sellpage` (`site_sellpage`), -+ KEY `site_pull` (`site_pull`), - KEY `site_realm` (`site_realm`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `source` -+ -- -+ - CREATE TABLE IF NOT EXISTS `source` ( - `src_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `src_channel_id` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 1003,1014 **** - KEY `src_xchan` (`src_xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `spam` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL, - `spam` int(11) NOT NULL DEFAULT '0', - `ham` int(11) NOT NULL DEFAULT '0', -! `term` char(255) NOT NULL, - `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), ---- 1282,1299 ---- - KEY `src_xchan` (`src_xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `spam` -+ -- -+ - CREATE TABLE IF NOT EXISTS `spam` ( - `id` int(11) NOT NULL AUTO_INCREMENT, -! `uid` int(11) NOT NULL DEFAULT '0', - `spam` int(11) NOT NULL DEFAULT '0', - `ham` int(11) NOT NULL DEFAULT '0', -! `term` char(255) NOT NULL DEFAULT '', - `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`), - KEY `uid` (`uid`), -*************** -*** 1017,1041 **** - KEY `term` (`term`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `sys_perms` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `cat` char(255) NOT NULL, -! `k` char(255) NOT NULL, - `v` mediumtext NOT NULL, -! `public_perm` tinyint(1) unsigned NOT NULL, - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `term` ( - `tid` int(10) unsigned NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', - `uid` int(10) unsigned NOT NULL DEFAULT '0', -! `oid` int(10) unsigned NOT NULL, -! `otype` tinyint(3) unsigned NOT NULL, -! `type` tinyint(3) unsigned NOT NULL, -! `term` char(255) NOT NULL, -! `url` char(255) NOT NULL, -! `imgurl` char(255) NOT NULL, - `term_hash` char(255) NOT NULL DEFAULT '', - `parent_hash` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`tid`), ---- 1302,1338 ---- - KEY `term` (`term`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `sys_perms` -+ -- -+ - CREATE TABLE IF NOT EXISTS `sys_perms` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `cat` char(255) NOT NULL DEFAULT '', -! `k` char(255) NOT NULL DEFAULT '', - `v` mediumtext NOT NULL, -! `public_perm` tinyint(1) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `term` -+ -- -+ - CREATE TABLE IF NOT EXISTS `term` ( - `tid` int(10) unsigned NOT NULL AUTO_INCREMENT, - `aid` int(10) unsigned NOT NULL DEFAULT '0', - `uid` int(10) unsigned NOT NULL DEFAULT '0', -! `oid` int(10) unsigned NOT NULL DEFAULT '0', -! `otype` tinyint(3) unsigned NOT NULL DEFAULT '0', -! `type` tinyint(3) unsigned NOT NULL DEFAULT '0', -! `term` char(255) NOT NULL DEFAULT '', -! `url` char(255) NOT NULL DEFAULT '', -! `imgurl` char(255) NOT NULL DEFAULT '', - `term_hash` char(255) NOT NULL DEFAULT '', - `parent_hash` char(255) NOT NULL DEFAULT '', - PRIMARY KEY (`tid`), -*************** -*** 1050,1071 **** - KEY `parent_hash` (`parent_hash`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `tokens` ( -! `id` varchar(40) NOT NULL, - `secret` text NOT NULL, -! `client_id` varchar(20) NOT NULL, -! `expires` bigint(20) unsigned NOT NULL, -! `scope` varchar(200) NOT NULL, -! `uid` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `client_id` (`client_id`), - KEY `expires` (`expires`), - KEY `uid` (`uid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `updates` ( - `ud_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `ud_hash` char(128) NOT NULL, - `ud_guid` char(255) NOT NULL DEFAULT '', - `ud_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ud_last` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', ---- 1347,1380 ---- - KEY `parent_hash` (`parent_hash`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `tokens` -+ -- -+ - CREATE TABLE IF NOT EXISTS `tokens` ( -! `id` varchar(40) NOT NULL DEFAULT '', - `secret` text NOT NULL, -! `client_id` varchar(20) NOT NULL DEFAULT '', -! `expires` bigint(20) unsigned NOT NULL DEFAULT '0', -! `scope` varchar(200) NOT NULL DEFAULT '', -! `uid` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `client_id` (`client_id`), - KEY `expires` (`expires`), - KEY `uid` (`uid`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `updates` -+ -- -+ - CREATE TABLE IF NOT EXISTS `updates` ( - `ud_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `ud_hash` char(128) NOT NULL DEFAULT '', - `ud_guid` char(255) NOT NULL DEFAULT '', - `ud_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ud_last` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -*************** -*** 1080,1085 **** ---- 1389,1400 ---- - KEY `ud_last` (`ud_last`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `verify` -+ -- -+ - CREATE TABLE IF NOT EXISTS `verify` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `channel` int(10) unsigned NOT NULL DEFAULT '0', -*************** -*** 1095,1100 **** ---- 1410,1421 ---- - KEY `created` (`created`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `vote` -+ -- -+ - CREATE TABLE IF NOT EXISTS `vote` ( - `vote_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `vote_poll` int(11) NOT NULL DEFAULT '0', -*************** -*** 1107,1112 **** ---- 1428,1439 ---- - KEY `vote_element` (`vote_element`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xchan` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xchan` ( - `xchan_hash` char(255) NOT NULL, - `xchan_guid` char(255) NOT NULL DEFAULT '', -*************** -*** 1139,1144 **** ---- 1466,1477 ---- - KEY `xchan_follow` (`xchan_follow`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xchat` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xchat` ( - `xchat_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `xchat_url` char(255) NOT NULL DEFAULT '', -*************** -*** 1150,1162 **** - KEY `xchat_desc` (`xchat_desc`), - KEY `xchat_xchan` (`xchat_xchan`), - KEY `xchat_edited` (`xchat_edited`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `xconfig` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `xchan` char(255) NOT NULL, -! `cat` char(255) NOT NULL, -! `k` char(255) NOT NULL, - `v` mediumtext NOT NULL, - PRIMARY KEY (`id`), - KEY `xchan` (`xchan`), ---- 1483,1501 ---- - KEY `xchat_desc` (`xchat_desc`), - KEY `xchat_xchan` (`xchat_xchan`), - KEY `xchat_edited` (`xchat_edited`) -! ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -! -! -- -------------------------------------------------------- -! -! -- -! -- Table structure for table `xconfig` -! -- - - CREATE TABLE IF NOT EXISTS `xconfig` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `xchan` char(255) NOT NULL DEFAULT '', -! `cat` char(255) NOT NULL DEFAULT '', -! `k` char(255) NOT NULL DEFAULT '', - `v` mediumtext NOT NULL, - PRIMARY KEY (`id`), - KEY `xchan` (`xchan`), -*************** -*** 1164,1169 **** ---- 1503,1514 ---- - KEY `k` (`k`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xign` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xign` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `uid` int(11) NOT NULL DEFAULT '0', -*************** -*** 1173,1178 **** ---- 1518,1529 ---- - KEY `xchan` (`xchan`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xlink` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xlink` ( - `xlink_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `xlink_xchan` char(255) NOT NULL DEFAULT '', -*************** -*** 1186,1191 **** ---- 1537,1548 ---- - KEY `xlink_rating` (`xlink_rating`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xprof` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xprof` ( - `xprof_hash` char(255) NOT NULL, - `xprof_age` tinyint(3) unsigned NOT NULL DEFAULT '0', -*************** -*** 1216,1224 **** - KEY `xprof_hometown` (`xprof_hometown`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - - CREATE TABLE IF NOT EXISTS `xtag` ( - `xtag_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `xtag_hash` char(255) NOT NULL, - `xtag_term` char(255) NOT NULL DEFAULT '', - `xtag_flags` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`xtag_id`), ---- 1573,1587 ---- - KEY `xprof_hometown` (`xprof_hometown`) - ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -+ -- -------------------------------------------------------- -+ -+ -- -+ -- Table structure for table `xtag` -+ -- -+ - CREATE TABLE IF NOT EXISTS `xtag` ( - `xtag_id` int(10) unsigned NOT NULL AUTO_INCREMENT, -! `xtag_hash` char(255) NOT NULL DEFAULT '', - `xtag_term` char(255) NOT NULL DEFAULT '', - `xtag_flags` int(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`xtag_id`), diff --git a/install/htconfig.sample.php b/install/htconfig.sample.php index 07725e3f4..509942530 100755 --- a/install/htconfig.sample.php +++ b/install/htconfig.sample.php @@ -12,7 +12,7 @@ // Then set the following for your MySQL installation -$db_host = 'your.mysqlhost.com'; // Use 'localhost' if you aren't using a remote server +$db_host = 'your.mysqlhost.com'; // Use 'localhost' or ':/path/to/socket.file' if you aren't using a remote server $db_port = 0; // leave 0 for default or set your port $db_user = 'mysqlusername'; $db_pass = 'mysqlpassword'; diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index cb4a3fa74..e7550455f 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -269,24 +269,6 @@ CREATE TABLE IF NOT EXISTS `channel` ( `channel_allow_gid` mediumtext NOT NULL, `channel_deny_cid` mediumtext NOT NULL, `channel_deny_gid` mediumtext NOT NULL, - `channel_r_stream` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_r_profile` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_r_photos` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_r_abook` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_stream` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_wall` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_tagwall` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_comment` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_mail` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_photos` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_chat` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_a_delegate` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_r_storage` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_storage` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_r_pages` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_pages` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_a_republish` int(10) unsigned NOT NULL DEFAULT 0 , - `channel_w_like` int(10) unsigned NOT NULL DEFAULT 0 , `channel_removed` tinyint(1) NOT NULL DEFAULT 0 , `channel_system` tinyint(1) NOT NULL DEFAULT 0 , `channel_moved` char(191) NOT NULL DEFAULT '', @@ -683,7 +665,7 @@ CREATE TABLE IF NOT EXISTS `item` ( KEY `mimetype` (`mimetype`), KEY `mid` (`mid`), KEY `parent_mid` (`parent_mid`), - KEY `uid_mid` (`mid`,`uid`), + KEY `uid_mid` (`uid`,`mid`), KEY `comment_policy` (`comment_policy`), KEY `layout_mid` (`layout_mid`), KEY `public_policy` (`public_policy`), @@ -1342,7 +1324,8 @@ CREATE TABLE IF NOT EXISTS `xchan` ( KEY `xchan_selfcensored` (`xchan_selfcensored`), KEY `xchan_system` (`xchan_system`), KEY `xchan_pubforum` (`xchan_pubforum`), - KEY `xchan_deleted` (`xchan_deleted`) + KEY `xchan_deleted` (`xchan_deleted`), + KEY `xchan_photo_m` (`xchan_photo_m`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE IF NOT EXISTS `xchat` ( diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index e56e054b0..c1c222b37 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -650,7 +650,7 @@ create index "item_revision" on item ("revision"); create index "item_mimetype" on item ("mimetype"); create index "item_mid" on item ("mid"); create index "item_parent_mid" on item ("parent_mid"); -create index "item_uid_mid" on item ("mid","uid"); +create index "item_uid_mid" on item ("uid","mid"); create index "item_public_policy" on item ("public_policy"); create index "item_comment_policy" on item ("comment_policy"); create index "item_layout_mid" on item ("layout_mid"); @@ -1312,6 +1312,7 @@ create index "xchan_selfcensored" on xchan ("xchan_selfcensored"); create index "xchan_system" on xchan ("xchan_system"); create index "xchan_pubforum" on xchan ("xchan_pubforum"); create index "xchan_deleted" on xchan ("xchan_deleted"); +create index "xchan_photo_m" on xchan ("xchan_photo_m"); CREATE TABLE "xchat" ( "xchat_id" serial NOT NULL, diff --git a/library/jgrowl/.gitignore b/library/jgrowl/.gitignore new file mode 100644 index 000000000..385e49ef1 --- /dev/null +++ b/library/jgrowl/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules/ +jGrowl.iml +jGrowl.ipr +jGrowl.iws diff --git a/library/jgrowl/Gruntfile.js b/library/jgrowl/Gruntfile.js new file mode 100644 index 000000000..fed0fceee --- /dev/null +++ b/library/jgrowl/Gruntfile.js @@ -0,0 +1,61 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + uglify: { + options: { + sourceMap: true, + sourceMapName: 'jquery.jgrowl.map' + }, + jgrowl: { + files: { + 'jquery.jgrowl.min.js': ['jquery.jgrowl.js'] + } + } + }, + less: { + jgrowl: { + files: { + "jquery.jgrowl.css": "less/jgrowl.less" + } + } + }, + cssmin: { + jgrowl: { + expand: true, + src: 'jquery.jgrowl.css', + ext: '.jgrowl.min.css' + } + }, + jshint: { + files: ['Gruntfile.js', 'jquery.jgrowl.js'], + options: { + // options here to override JSHint defaults + globals: { + jQuery: true, + console: true, + module: true, + document: true + } + } + }, + watch: { + scripts: { + files: ['jquery.jgrowl.js', 'less/*'], + tasks: ['jshint', 'less', 'cssmin', 'uglify'], + options: { + spawn: false + } + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-less'); + + grunt.registerTask('test', ['jshint']); + grunt.registerTask('default', ['jshint', 'uglify', 'less', 'cssmin']); +}; diff --git a/library/jgrowl/LICENSE b/library/jgrowl/LICENSE new file mode 100644 index 000000000..e70a54a58 --- /dev/null +++ b/library/jgrowl/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2012 Stan Lemon + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/library/jgrowl/README b/library/jgrowl/README deleted file mode 100644 index d0f1a62ad..000000000 --- a/library/jgrowl/README +++ /dev/null @@ -1,3 +0,0 @@ -https://github.com/stanlemon/jGrowl - -jGrowl is free and open source, it's distributed under the MIT and GPL licenses diff --git a/library/jgrowl/README.md b/library/jgrowl/README.md new file mode 100644 index 000000000..7dfd85637 --- /dev/null +++ b/library/jgrowl/README.md @@ -0,0 +1,75 @@ +# jGrowl +jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works. The idea is simple, deliver notifications to the end user in a noticeable way that doesn't obstruct the work flow and yet keeps the user informed. + +## Installation +jGrowl can be added to your project using package managers like bower and npm or directly into your html using cdnjs, as well as the good old fashioned copy-paste into your project directory. + +Use cdnjs: + +```html + + +``` + +Install with bower + +``` +bower install jgrowl +``` + +Install with npm + +``` +npm install jgrowl +``` + +```js +// Sample 1 +$.jGrowl("Hello world!"); +// Sample 2 +$.jGrowl("Stick this!", { sticky: true }); +// Sample 3 +$.jGrowl("A message with a header", { header: 'Important' }); +// Sample 4 +$.jGrowl("A message that will live a little longer.", { life: 10000 }); +// Sample 5 +$.jGrowl("A message with a beforeOpen callback and a different opening animation.", { + beforeClose: function(e,m) { + alert('About to close this notification!'); + }, + animateOpen: { + height: 'show' + } +}); +``` + +## Configuration Options +| Option | Default | Description | +|------------------|--------------------------------------|------------------------------------------------------------| +| pool | 0 | Limit the number of messages appearing at a given time to the number in the pool. | +| header | empty | Optional header to prefix the message, this is often helpful for associating messages to each other. | +| group | empty | A css class to be applied to notifications when they are created, useful for 'grouping' notifications by a css selector. | +| sticky | false | When set to true a message will stick to the screen until it is intentionally closed by the user. | +| position | top-right | Designates a class which is applied to the jGrowl container and controls its position on the screen. By Default there are five options available, top-left, top-right, bottom-left, bottom-right, center. This must be changed in the defaults before the startup method is called. | +| appendTo | body | The element where our jGrowl messages are appended to. The default is `body` but feel free to define another one. | +| glue | after | Designates whether a jGrowl notification should be appended to the container after all notifications, or whether it should be prepended to the container before all notifications. Options are after or before. | +| theme | default | A CSS class designating custom styling for this particular message, intended for use with jQuery UI. | +| themeState | highlight | A CSS class designating custom styling for this particular message and its state, intended for use with jQuery UI. | +| corners | 10px | If the corners jQuery plugin is include this option specifies the curvature radius to be used for the notifications as they are created. | +| check | 250 | The frequency that jGrowl should check for messages to be scrubbed from the screen.This must be changed in the defaults before the startup method is called. | +| life | 3000 | The lifespan of a non-sticky message on the screen. | +| closeDuration | normal | The animation speed used to close a notification. | +| openDuration | normal | The animation speed used to open a notification. | +| easing | swing | The easing method to be used with the animation for opening and closing a notification. | +| closer | true | Whether or not the close-all button should be used when more then one notification appears on the screen. Optionally this property can be set to a function which will be used as a callback when the close all button is clicked. This must be changed in the defaults before the startup method is called. | +| closeTemplate | × | This content is used for the individual notification close links that are added to the corner of a notification. This must be changed in the defaults before the startup method is called. | +| closerTemplate | <div>[ close all ]</div> | This content is used for the close-all link that is added to the bottom of a jGrowl container when it contains more than one notification. This must be changed in the defaults before the startup method is called. | +| log | function(e,m,o) {} | Callback to be used before anything is done with the notification. This is intended to be used if the user would like to have some type of logging mechanism for all notifications passed to jGrowl. This callback receives the notification's DOM context, the notification's message and its option object. | +| beforeOpen | function(e,m,o) {} | Callback to be used before a new notification is opened. This callback receives the notification's DOM context, the notification's message and its option object. | +| afterOpen | function(e,m,o) {} | Callback to be used after a new notification is opened. This callback receives the notification's DOM context, the notification's message and its option object. | +| open | function(e,m,o) {} | Callback to be used when a new notification is opened. This callback receives the notification's DOM context, the notifications message and its option object. | +| beforeClose | function(e,m,o) {} | Callback to be used before a new notification is closed. This callback receives the notification's DOM context, the notification's message and its option object. | +| close | function(e,m,o) {} | Callback to be used when a new notification is closed. This callback receives the notification's DOM context, the notification's message and its option object. | +| click | function(e,m,o) {} | Callback to be used when a notification is clicked. This callback receives the notification's DOM context, the notification's message and its option object. | +| animateOpen | { opacity: 'show' } | The animation properties to use when opening a new notification (default to fadeOut). | +| animateClose | { opacity: 'hide' } | The animation properties to use when closing a new notification (defaults to fadeIn). | diff --git a/library/jgrowl/bower.json b/library/jgrowl/bower.json new file mode 100644 index 000000000..15cfc754b --- /dev/null +++ b/library/jgrowl/bower.json @@ -0,0 +1,32 @@ +{ + "name": "jGrowl", + "version": "1.4.5", + "homepage": "https://github.com/stanlemon/jGrowl", + "authors": [ + "Stan Lemon " + ], + "description": "jGrowl is an unobtrusive notification system for web applications.", + "main": [ + "jquery.jgrowl.css", + "jquery.jgrowl.js" + ], + "keywords": [ + "growl", + "jgrowl", + "jquery", + "toaster", + "notification", + "message" + ], + "license": "MIT", + "dependencies": { + "jquery": ">=1.4" + }, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/library/jgrowl/examples/appendTo.html b/library/jgrowl/examples/appendTo.html new file mode 100644 index 000000000..3eb0f4d27 --- /dev/null +++ b/library/jgrowl/examples/appendTo.html @@ -0,0 +1,103 @@ + + + + jGrowl Examples + + + + + + + +
I'm the dummy navigation
+ +

Append To Another DOM-Object

+ + diff --git a/library/jgrowl/examples/bootstrap.html b/library/jgrowl/examples/bootstrap.html new file mode 100644 index 000000000..6e069a3b9 --- /dev/null +++ b/library/jgrowl/examples/bootstrap.html @@ -0,0 +1,91 @@ + + + + + + + + + + jGrowl and Bootstrap + + + + + + + + + + + +
+ + + +
+ +
+

jGrowl and Bootstrap

+

This is a Bootstrap starter template with jGrowl integrated. As you can see it's extremely easy to make jGrowl look and feel like part of Bootstrap.

+
+
+
+ + + + + + + + + + diff --git a/library/jgrowl/examples/jgrowl.html b/library/jgrowl/examples/jgrowl.html new file mode 100755 index 000000000..e10fdd6cb --- /dev/null +++ b/library/jgrowl/examples/jgrowl.html @@ -0,0 +1,171 @@ + + + + jGrowl Examples + + + + + + + +

jGrowl Tests

+ +

Create a new message.

+ +

Shutdown bottom-left container.

+ +
An extra wide node, watch as the jGrowl containers stay put in the corners of the screen..
+ +

Log:

+ +
+ + diff --git a/library/jgrowl/jgrowl.jquery.json b/library/jgrowl/jgrowl.jquery.json new file mode 100644 index 000000000..c5f0756c9 --- /dev/null +++ b/library/jgrowl/jgrowl.jquery.json @@ -0,0 +1,40 @@ +{ + "name": "jgrowl", + "filename": "jquery.jgrowl.min.js", + "title": "jGrowl", + "description": "jGrowl is a jQuery plugin that raises unobtrusive messages within the browser, similar to the way that OS X's Growl Framework works. The idea is simple, deliver notifications to the end user in a noticeable way that doesn't obstruct the work flow and yet keeps the user informed.", + "keywords": [ + "growl", + "jgrowl", + "jquery", + "toaster", + "notification", + "message" + ], + "version": "1.4.3", + "author": { + "name": "Stan Lemon", + "email": "stosh1985@gmail.com", + "url": "http://stanlemon.net" + }, + "maintainers": [ + { + "name": "Stan Lemon", + "email": "stosh1985@gmail.com", + "url": "http://stanlemon.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/stanlemon/jGrowl/blob/master/LICENSE" + } + ], + "bugs": "https://github.com/stanlemon/jGrowl/issues", + "homepage": "https://github.com/stanlemon/jGrowl", + "docs": "https://github.com/stanlemon/jGrowl", + "download": "https://github.com/stanlemon/jGrowl/archive/master.zip", + "dependencies": { + "jquery": ">=1.4" + } +} diff --git a/library/jgrowl/jquery.jgrowl.css b/library/jgrowl/jquery.jgrowl.css index ea3948415..4a00b60f7 100644 --- a/library/jgrowl/jquery.jgrowl.css +++ b/library/jgrowl/jquery.jgrowl.css @@ -1 +1,100 @@ -.jGrowl{z-index:9999;color:#fff;font-size:12px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:fixed}.jGrowl.top-left{left:0;top:0}.jGrowl.top-right{right:0;top:0}.jGrowl.bottom-left{left:0;bottom:0}.jGrowl.bottom-right{right:0;bottom:0}.jGrowl.center{top:0;width:50%;left:25%}.jGrowl.center .jGrowl-closer,.jGrowl.center .jGrowl-notification{margin-left:auto;margin-right:auto}.jGrowl-notification{background-color:#000;opacity:.9;-ms-filter:alpha(90);filter:alpha(90);zoom:1;width:250px;padding:10px;margin:10px;text-align:left;display:none;border-radius:5px;min-height:40px}.jGrowl-notification .ui-state-highlight,.jGrowl-notification .ui-widget-content .ui-state-highlight,.jGrowl-notification .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}.jGrowl-notification .jGrowl-header{font-weight:700;font-size:.85em}.jGrowl-notification .jGrowl-close{background-color:transparent;color:inherit;border:none;z-index:99;float:right;font-weight:700;font-size:1em;cursor:pointer}.jGrowl-closer{background-color:#000;opacity:.9;-ms-filter:alpha(90);filter:alpha(90);zoom:1;width:250px;padding:10px;margin:10px;display:none;border-radius:5px;padding-top:4px;padding-bottom:4px;cursor:pointer;font-size:.9em;font-weight:700;text-align:center}.jGrowl-closer .ui-state-highlight,.jGrowl-closer .ui-widget-content .ui-state-highlight,.jGrowl-closer .ui-widget-header .ui-state-highlight{border:1px solid #000;background:#000;color:#fff}@media print{.jGrowl{display:none}} \ No newline at end of file +.jGrowl { + z-index: 9999; + color: #ffffff; + font-size: 12px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + position: fixed; +} +.jGrowl.top-left { + left: 0px; + top: 0px; +} +.jGrowl.top-right { + right: 0px; + top: 0px; +} +.jGrowl.bottom-left { + left: 0px; + bottom: 0px; +} +.jGrowl.bottom-right { + right: 0px; + bottom: 0px; +} +.jGrowl.center { + top: 0px; + width: 50%; + left: 25%; +} +.jGrowl.center .jGrowl-notification, +.jGrowl.center .jGrowl-closer { + margin-left: auto; + margin-right: auto; +} +.jGrowl-notification { + background-color: #000000; + opacity: 0.9; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100)); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100)); + zoom: 1; + width: 250px; + padding: 10px; + margin: 10px; + text-align: left; + display: none; + border-radius: 5px; + min-height: 40px; +} +.jGrowl-notification .ui-state-highlight, +.jGrowl-notification .ui-widget-content .ui-state-highlight, +.jGrowl-notification .ui-widget-header .ui-state-highlight { + border: 1px solid #000; + background: #000; + color: #fff; +} +.jGrowl-notification .jGrowl-header { + font-weight: bold; + font-size: .85em; +} +.jGrowl-notification .jGrowl-close { + background-color: transparent; + color: inherit; + border: none; + z-index: 99; + float: right; + font-weight: bold; + font-size: 1em; + cursor: pointer; +} +.jGrowl-closer { + background-color: #000000; + opacity: 0.9; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100)); + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=(0.9*100)); + zoom: 1; + width: 250px; + padding: 10px; + margin: 10px; + text-align: left; + display: none; + border-radius: 5px; + padding-top: 4px; + padding-bottom: 4px; + cursor: pointer; + font-size: .9em; + font-weight: bold; + text-align: center; +} +.jGrowl-closer .ui-state-highlight, +.jGrowl-closer .ui-widget-content .ui-state-highlight, +.jGrowl-closer .ui-widget-header .ui-state-highlight { + border: 1px solid #000; + background: #000; + color: #fff; +} +/** Hide jGrowl when printing **/ +@media print { + .jGrowl { + display: none; + } +} diff --git a/library/jgrowl/jquery.jgrowl.js b/library/jgrowl/jquery.jgrowl.js new file mode 100755 index 000000000..d5444d438 --- /dev/null +++ b/library/jgrowl/jquery.jgrowl.js @@ -0,0 +1,399 @@ +/** + * jGrowl 1.4.5 + * + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * + * Written by Stan Lemon + * Last updated: 2015.02.01 + * + * jGrowl is a jQuery plugin implementing unobtrusive userland notifications. These + * notifications function similarly to the Growl Framework available for + * Mac OS X (http://growl.info). + * + * To Do: + * - Move library settings to containers and allow them to be changed per container + * + * Changes in 1.4.5 + * - Fixed arguement list for click callback, thanks @timotheeg + * + * Changes in 1.4.4 + * - Revert word-break changes, thanks @curtisgibby + * + * Changes in 1.4.3 + * - Fixed opactiy in LESS for older version of IE + * + * Changes in 1.4.2 + * - Added word-break to less/css + * + * Changes in 1.4.1 + * - Added appendTo option + * - jQuery compatibility updates + * - Add check for closing a notification before it opens + * + * Changes in 1.4.0 + * - Removed IE6 support + * - Added LESS support + * + * Changes in 1.3.0 + * - Added non-vendor border-radius to stylesheet + * - Added grunt for generating minified js and css + * - Added npm package info + * - Added bower package info + * - Updates for jshint + * + * Changes in 1.2.13 + * - Fixed clearing interval when the container shuts down + * + * Changes in 1.2.12 + * - Added compressed versions using UglifyJS and Sqwish + * - Improved README with configuration options explanation + * - Added a source map + * + * Changes in 1.2.11 + * - Fix artifacts left behind by the shutdown method and text-cleanup + * + * Changes in 1.2.10 + * - Fix beforeClose to be called in click event + * + * Changes in 1.2.9 + * - Fixed BC break in jQuery 2.0 beta + * + * Changes in 1.2.8 + * - Fixes for jQuery 1.9 and the MSIE6 check, note that with jQuery 2.0 support + * jGrowl intends to drop support for IE6 altogether + * + * Changes in 1.2.6 + * - Fixed js error when a notification is opening and closing at the same time + * + * Changes in 1.2.5 + * - Changed wrapper jGrowl's options usage to "o" instead of $.jGrowl.defaults + * - Added themeState option to control 'highlight' or 'error' for jQuery UI + * - Ammended some CSS to provide default positioning for nested usage. + * - Changed some CSS to be prefixed with jGrowl- to prevent namespacing issues + * - Added two new options - openDuration and closeDuration to allow + * better control of notification open and close speeds, respectively + * Patch contributed by Jesse Vincet. + * - Added afterOpen callback. Patch contributed by Russel Branca. + * + * Changes in 1.2.4 + * - Fixed IE bug with the close-all button + * - Fixed IE bug with the filter CSS attribute (special thanks to gotwic) + * - Update IE opacity CSS + * - Changed font sizes to use "em", and only set the base style + * + * Changes in 1.2.3 + * - The callbacks no longer use the container as context, instead they use the actual notification + * - The callbacks now receive the container as a parameter after the options parameter + * - beforeOpen and beforeClose now check the return value, if it's false - the notification does + * not continue. The open callback will also halt execution if it returns false. + * - Fixed bug where containers would get confused + * - Expanded the pause functionality to pause an entire container. + * + * Changes in 1.2.2 + * - Notification can now be theme rolled for jQuery UI, special thanks to Jeff Chan! + * + * Changes in 1.2.1 + * - Fixed instance where the interval would fire the close method multiple times. + * - Added CSS to hide from print media + * - Fixed issue with closer button when div { position: relative } is set + * - Fixed leaking issue with multiple containers. Special thanks to Matthew Hanlon! + * + * Changes in 1.2.0 + * - Added message pooling to limit the number of messages appearing at a given time. + * - Closing a notification is now bound to the notification object and triggered by the close button. + * + * Changes in 1.1.2 + * - Added iPhone styled example + * - Fixed possible IE7 bug when determining if the ie6 class shoudl be applied. + * - Added template for the close button, so that it's content could be customized. + * + * Changes in 1.1.1 + * - Fixed CSS styling bug for ie6 caused by a mispelling + * - Changes height restriction on default notifications to min-height + * - Added skinned examples using a variety of images + * - Added the ability to customize the content of the [close all] box + * - Added jTweet, an example of using jGrowl + Twitter + * + * Changes in 1.1.0 + * - Multiple container and instances. + * - Standard $.jGrowl() now wraps $.fn.jGrowl() by first establishing a generic jGrowl container. + * - Instance methods of a jGrowl container can be called by $.fn.jGrowl(methodName) + * - Added glue preferenced, which allows notifications to be inserted before or after nodes in the container + * - Added new log callback which is called before anything is done for the notification + * - Corner's attribute are now applied on an individual notification basis. + * + * Changes in 1.0.4 + * - Various CSS fixes so that jGrowl renders correctly in IE6. + * + * Changes in 1.0.3 + * - Fixed bug with options persisting across notifications + * - Fixed theme application bug + * - Simplified some selectors and manipulations. + * - Added beforeOpen and beforeClose callbacks + * - Reorganized some lines of code to be more readable + * - Removed unnecessary this.defaults context + * - If corners plugin is present, it's now customizable. + * - Customizable open animation. + * - Customizable close animation. + * - Customizable animation easing. + * - Added customizable positioning (top-left, top-right, bottom-left, bottom-right, center) + * + * Changes in 1.0.2 + * - All CSS styling is now external. + * - Added a theme parameter which specifies a secondary class for styling, such + * that notifications can be customized in appearance on a per message basis. + * - Notification life span is now customizable on a per message basis. + * - Added the ability to disable the global closer, enabled by default. + * - Added callbacks for when a notification is opened or closed. + * - Added callback for the global closer. + * - Customizable animation speed. + * - jGrowl now set itself up and tears itself down. + * + * Changes in 1.0.1: + * - Removed dependency on metadata plugin in favor of .data() + * - Namespaced all events + */ +(function($) { + /** jGrowl Wrapper - Establish a base jGrowl Container for compatibility with older releases. **/ + $.jGrowl = function( m , o ) { + // To maintain compatibility with older version that only supported one instance we'll create the base container. + if ( $('#jGrowl').length === 0 ) + $('
').addClass( (o && o.position) ? o.position : $.jGrowl.defaults.position ).appendTo( (o && o.appendTo) ? o.appendTo : $.jGrowl.defaults.appendTo ); + + // Create a notification on the container. + $('#jGrowl').jGrowl(m,o); + }; + + + /** Raise jGrowl Notification on a jGrowl Container **/ + $.fn.jGrowl = function( m , o ) { + // Short hand for passing in just an object to this method + if ( o === undefined && $.isPlainObject(m) ) { + o = m; + m = o.message; + } + + if ( $.isFunction(this.each) ) { + var args = arguments; + + return this.each(function() { + /** Create a jGrowl Instance on the Container if it does not exist **/ + if ( $(this).data('jGrowl.instance') === undefined ) { + $(this).data('jGrowl.instance', $.extend( new $.fn.jGrowl(), { notifications: [], element: null, interval: null } )); + $(this).data('jGrowl.instance').startup( this ); + } + + /** Optionally call jGrowl instance methods, or just raise a normal notification **/ + if ( $.isFunction($(this).data('jGrowl.instance')[m]) ) { + $(this).data('jGrowl.instance')[m].apply( $(this).data('jGrowl.instance') , $.makeArray(args).slice(1) ); + } else { + $(this).data('jGrowl.instance').create( m , o ); + } + }); + } + }; + + $.extend( $.fn.jGrowl.prototype , { + + /** Default JGrowl Settings **/ + defaults: { + pool: 0, + header: '', + group: '', + sticky: false, + position: 'top-right', + appendTo: 'body', + glue: 'after', + theme: 'default', + themeState: 'highlight', + corners: '10px', + check: 250, + life: 3000, + closeDuration: 'normal', + openDuration: 'normal', + easing: 'swing', + closer: true, + closeTemplate: '×', + closerTemplate: '
[ close all ]
', + log: function() {}, + beforeOpen: function() {}, + afterOpen: function() {}, + open: function() {}, + beforeClose: function() {}, + close: function() {}, + click: function() {}, + animateOpen: { + opacity: 'show' + }, + animateClose: { + opacity: 'hide' + } + }, + + notifications: [], + + /** jGrowl Container Node **/ + element: null, + + /** Interval Function **/ + interval: null, + + /** Create a Notification **/ + create: function( message , options ) { + var o = $.extend({}, this.defaults, options); + + /* To keep backward compatibility with 1.24 and earlier, honor 'speed' if the user has set it */ + if (typeof o.speed !== 'undefined') { + o.openDuration = o.speed; + o.closeDuration = o.speed; + } + + this.notifications.push({ message: message , options: o }); + + o.log.apply( this.element , [this.element,message,o] ); + }, + + render: function( n ) { + var self = this; + var message = n.message; + var o = n.options; + + // Support for jQuery theme-states, if this is not used it displays a widget header + o.themeState = (o.themeState === '') ? '' : 'ui-state-' + o.themeState; + + var notification = $('
') + .addClass('jGrowl-notification alert ' + o.themeState + ' ui-corner-all' + ((o.group !== undefined && o.group !== '') ? ' ' + o.group : '')) + .append($('
',trigger:"hover focus",title:"",delay:0,html:!(An={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(Dn={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},Nn="out",kn={HIDE:"hide"+wn,HIDDEN:"hidden"+wn,SHOW:(On="show")+wn,SHOWN:"shown"+wn,INSERTED:"inserted"+wn,CLICK:"click"+wn,FOCUSIN:"focusin"+wn,FOCUSOUT:"focusout"+wn,MOUSEENTER:"mouseenter"+wn,MOUSELEAVE:"mouseleave"+wn},xn="fade",Pn="show",Ln=".tooltip-inner",jn=".arrow",Hn="hover",Mn="focus",Fn="click",Wn="manual",Rn=function(){function i(e,t){if("undefined"==typeof Ct)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=e,this.config=this._getConfig(t),this.tip=null,this._setListeners()}var e=i.prototype;return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(e){if(this._isEnabled)if(e){var t=this.constructor.DATA_KEY,n=yn(e.currentTarget).data(t);n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),yn(e.currentTarget).data(t,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(yn(this.getTipElement()).hasClass(Pn))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),yn.removeData(this.element,this.constructor.DATA_KEY),yn(this.element).off(this.constructor.EVENT_KEY),yn(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&yn(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===yn(this.element).css("display"))throw new Error("Please use show on visible elements");var e=yn.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){yn(this.element).trigger(e);var n=yn.contains(this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=we.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&yn(i).addClass(xn);var o="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var a=!1===this.config.container?document.body:yn(document).find(this.config.container);yn(i).data(this.constructor.DATA_KEY,this),yn.contains(this.element.ownerDocument.documentElement,this.tip)||yn(i).appendTo(a),yn(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new Ct(this.element,i,{placement:s,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:jn},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(e){e.originalPlacement!==e.placement&&t._handlePopperPlacementChange(e)},onUpdate:function(e){t._handlePopperPlacementChange(e)}}),yn(i).addClass(Pn),"ontouchstart"in document.documentElement&&yn(document.body).children().on("mouseover",null,yn.noop);var l=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,yn(t.element).trigger(t.constructor.Event.SHOWN),e===Nn&&t._leave(null,t)};if(yn(this.tip).hasClass(xn)){var c=we.getTransitionDurationFromElement(this.tip);yn(this.tip).one(we.TRANSITION_END,l).emulateTransitionEnd(c)}else l()}},e.hide=function(e){var t=this,n=this.getTipElement(),i=yn.Event(this.constructor.Event.HIDE),r=function(){t._hoverState!==On&&n.parentNode&&n.parentNode.removeChild(n),t._cleanTipClass(),t.element.removeAttribute("aria-describedby"),yn(t.element).trigger(t.constructor.Event.HIDDEN),null!==t._popper&&t._popper.destroy(),e&&e()};if(yn(this.element).trigger(i),!i.isDefaultPrevented()){if(yn(n).removeClass(Pn),"ontouchstart"in document.documentElement&&yn(document.body).children().off("mouseover",null,yn.noop),this._activeTrigger[Fn]=!1,this._activeTrigger[Mn]=!1,this._activeTrigger[Hn]=!1,yn(this.tip).hasClass(xn)){var o=we.getTransitionDurationFromElement(n);yn(n).one(we.TRANSITION_END,r).emulateTransitionEnd(o)}else r();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(e){yn(this.getTipElement()).addClass(Tn+"-"+e)},e.getTipElement=function(){return this.tip=this.tip||yn(this.config.template)[0],this.tip},e.setContent=function(){var e=this.getTipElement();this.setElementContent(yn(e.querySelectorAll(Ln)),this.getTitle()),yn(e).removeClass(xn+" "+Pn)},e.setElementContent=function(e,t){var n=this.config.html;"object"==typeof t&&(t.nodeType||t.jquery)?n?yn(t).parent().is(e)||e.empty().append(t):e.text(yn(t).text()):e[n?"html":"text"](t)},e.getTitle=function(){var e=this.element.getAttribute("data-original-title");return e||(e="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),e},e._getAttachment=function(e){return An[e.toUpperCase()]},e._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)yn(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(e){return i.toggle(e)});else if(e!==Wn){var t=e===Hn?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=e===Hn?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;yn(i.element).on(t,i.config.selector,function(e){return i._enter(e)}).on(n,i.config.selector,function(e){return i._leave(e)})}yn(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var e=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==e)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(e,t){var n=this.constructor.DATA_KEY;(t=t||yn(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),yn(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusin"===e.type?Mn:Hn]=!0),yn(t.getTipElement()).hasClass(Pn)||t._hoverState===On?t._hoverState=On:(clearTimeout(t._timeout),t._hoverState=On,t.config.delay&&t.config.delay.show?t._timeout=setTimeout(function(){t._hoverState===On&&t.show()},t.config.delay.show):t.show())},e._leave=function(e,t){var n=this.constructor.DATA_KEY;(t=t||yn(e.currentTarget).data(n))||(t=new this.constructor(e.currentTarget,this._getDelegateConfig()),yn(e.currentTarget).data(n,t)),e&&(t._activeTrigger["focusout"===e.type?Mn:Hn]=!1),t._isWithActiveTrigger()||(clearTimeout(t._timeout),t._hoverState=Nn,t.config.delay&&t.config.delay.hide?t._timeout=setTimeout(function(){t._hoverState===Nn&&t.hide()},t.config.delay.hide):t.hide())},e._isWithActiveTrigger=function(){for(var e in this._activeTrigger)if(this._activeTrigger[e])return!0;return!1},e._getConfig=function(e){return"number"==typeof(e=l({},this.constructor.Default,yn(this.element).data(),"object"==typeof e&&e?e:{})).delay&&(e.delay={show:e.delay,hide:e.delay}),"number"==typeof e.title&&(e.title=e.title.toString()),"number"==typeof e.content&&(e.content=e.content.toString()),we.typeCheckConfig(En,e,this.constructor.DefaultType),e},e._getDelegateConfig=function(){var e={};if(this.config)for(var t in this.config)this.constructor.Default[t]!==this.config[t]&&(e[t]=this.config[t]);return e},e._cleanTipClass=function(){var e=yn(this.getTipElement()),t=e.attr("class").match(Sn);null!==t&&t.length&&e.removeClass(t.join(""))},e._handlePopperPlacementChange=function(e){var t=e.instance;this.tip=t.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(e.placement))},e._fixTransition=function(){var e=this.getTipElement(),t=this.config.animation;null===e.getAttribute("x-placement")&&(yn(e).removeClass(xn),this.config.animation=!1,this.hide(),this.show(),this.config.animation=t)},i._jQueryInterface=function(n){return this.each(function(){var e=yn(this).data(bn),t="object"==typeof n&&n;if((e||!/dispose|hide/.test(n))&&(e||(e=new i(this,t),yn(this).data(bn,e)),"string"==typeof n)){if("undefined"==typeof e[n])throw new TypeError('No method named "'+n+'"');e[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.1.3"}},{key:"Default",get:function(){return In}},{key:"NAME",get:function(){return En}},{key:"DATA_KEY",get:function(){return bn}},{key:"Event",get:function(){return kn}},{key:"EVENT_KEY",get:function(){return wn}},{key:"DefaultType",get:function(){return Dn}}]),i}(),yn.fn[En]=Rn._jQueryInterface,yn.fn[En].Constructor=Rn,yn.fn[En].noConflict=function(){return yn.fn[En]=Cn,Rn._jQueryInterface},Rn),Qi=(Bn="popover",Kn="."+(qn="bs.popover"),Qn=(Un=t).fn[Bn],Yn="bs-popover",Vn=new RegExp("(^|\\s)"+Yn+"\\S+","g"),zn=l({},Ki.Default,{placement:"right",trigger:"click",content:"",template:''}),Gn=l({},Ki.DefaultType,{content:"(string|element|function)"}),Jn="fade",Xn=".popover-header",$n=".popover-body",ei={HIDE:"hide"+Kn,HIDDEN:"hidden"+Kn,SHOW:(Zn="show")+Kn,SHOWN:"shown"+Kn,INSERTED:"inserted"+Kn,CLICK:"click"+Kn,FOCUSIN:"focusin"+Kn,FOCUSOUT:"focusout"+Kn,MOUSEENTER:"mouseenter"+Kn,MOUSELEAVE:"mouseleave"+Kn},ti=function(e){var t,n;function i(){return e.apply(this,arguments)||this}n=e,(t=i).prototype=Object.create(n.prototype),(t.prototype.constructor=t).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(e){Un(this.getTipElement()).addClass(Yn+"-"+e)},r.getTipElement=function(){return this.tip=this.tip||Un(this.config.template)[0],this.tip},r.setContent=function(){var e=Un(this.getTipElement());this.setElementContent(e.find(Xn),this.getTitle());var t=this._getContent();"function"==typeof t&&(t=t.call(this.element)),this.setElementContent(e.find($n),t),e.removeClass(Jn+" "+Zn)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var e=Un(this.getTipElement()),t=e.attr("class").match(Vn);null!==t&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||ethis._items.length-1||t<0))if(this._isSliding)p(this._element).one(q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=n=i.clientWidth&&n>=i.clientHeight}),h=0l[t]&&!i.escapeWithReference&&(n=Math.min(h[e],l[t]-("right"===t?h.width:h.height))),Kt({},e,n)}};return c.forEach(function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";h=Qt({},h,u[e](t))}),t.offsets.popper=h,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,s=-1!==["top","bottom"].indexOf(o),a=s?"right":"bottom",l=s?"left":"top",c=s?"width":"height";return n[a]r(i[a])&&(t.offsets.popper[l]=r(i[a])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!fe(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,a=r.reference,l=-1!==["left","right"].indexOf(o),c=l?"height":"width",h=l?"Top":"Left",u=h.toLowerCase(),f=l?"left":"top",d=l?"bottom":"right",p=Zt(i)[c];a[d]-ps[d]&&(t.offsets.popper[u]+=a[u]+p-s[d]),t.offsets.popper=Vt(t.offsets.popper);var m=a[u]+a[c]/2-p/2,g=Nt(t.instance.popper),_=parseFloat(g["margin"+h],10),v=parseFloat(g["border"+h+"Width"],10),y=m-t.offsets.popper[u]-_-v;return y=Math.max(Math.min(s[c]-p,y),0),t.arrowElement=i,t.offsets.arrow=(Kt(n={},u,Math.round(y)),Kt(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(p,m){if(oe(p.instance.modifiers,"inner"))return p;if(p.flipped&&p.placement===p.originalPlacement)return p;var g=Gt(p.instance.popper,p.instance.reference,m.padding,m.boundariesElement,p.positionFixed),_=p.placement.split("-")[0],v=te(_),y=p.placement.split("-")[1]||"",E=[];switch(m.behavior){case ge:E=[_,v];break;case _e:E=me(_);break;case ve:E=me(_,!0);break;default:E=m.behavior}return E.forEach(function(t,e){if(_!==t||E.length===e+1)return p;_=p.placement.split("-")[0],v=te(_);var n,i=p.offsets.popper,o=p.offsets.reference,r=Math.floor,s="left"===_&&r(i.right)>r(o.left)||"right"===_&&r(i.left)r(o.top)||"bottom"===_&&r(i.top)r(g.right),c=r(i.top)r(g.bottom),u="left"===_&&a||"right"===_&&l||"top"===_&&c||"bottom"===_&&h,f=-1!==["top","bottom"].indexOf(_),d=!!m.flipVariations&&(f&&"start"===y&&a||f&&"end"===y&&l||!f&&"start"===y&&c||!f&&"end"===y&&h);(s||u||d)&&(p.flipped=!0,(s||u)&&(_=E[e+1]),d&&(y="end"===(n=y)?"start":"start"===n?"end":n),p.placement=_+(y?"-"+y:""),p.offsets.popper=Qt({},p.offsets.popper,ee(p.instance.popper,p.offsets.reference,p.placement)),p=ie(p.instance.modifiers,p,"flip"))}),p},behavior:"flip",padding:5,boundariesElement:"viewport"},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,s=-1!==["left","right"].indexOf(n),a=-1===["top","left"].indexOf(n);return o[s?"left":"top"]=r[n]-(a?o[s?"width":"height"]:0),t.placement=te(e),t.offsets.popper=Vt(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!fe(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=ne(t.instance.modifiers,function(t){return"preventOverflow"===t.name}).boundaries;if(e.bottomn.right||e.top>n.bottom||e.rightdocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:vn},Ln="show",xn="out",Pn={HIDE:"hide"+Tn,HIDDEN:"hidden"+Tn,SHOW:"show"+Tn,SHOWN:"shown"+Tn,INSERTED:"inserted"+Tn,CLICK:"click"+Tn,FOCUSIN:"focusin"+Tn,FOCUSOUT:"focusout"+Tn,MOUSEENTER:"mouseenter"+Tn,MOUSELEAVE:"mouseleave"+Tn},Hn="fade",jn="show",Rn=".tooltip-inner",Fn=".arrow",Mn="hover",Wn="focus",Un="click",Bn="manual",qn=function(){function i(t,e){if("undefined"==typeof be)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=p(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),p(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(p(this.getTipElement()).hasClass(jn))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),p.removeData(this.element,this.constructor.DATA_KEY),p(this.element).off(this.constructor.EVENT_KEY),p(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&p(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===p(this.element).css("display"))throw new Error("Please use show on visible elements");var t=p.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){p(this.element).trigger(t);var n=m.findShadowRoot(this.element),i=p.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=m.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&p(o).addClass(Hn);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();p(o).data(this.constructor.DATA_KEY,this),p.contains(this.element.ownerDocument.documentElement,this.tip)||p(o).appendTo(l),p(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new be(this.element,o,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:Fn},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),p(o).addClass(jn),"ontouchstart"in document.documentElement&&p(document.body).children().on("mouseover",null,p.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,p(e.element).trigger(e.constructor.Event.SHOWN),t===xn&&e._leave(null,e)};if(p(this.tip).hasClass(Hn)){var h=m.getTransitionDurationFromElement(this.tip);p(this.tip).one(m.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=p.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==Ln&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),p(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(p(this.element).trigger(i),!i.isDefaultPrevented()){if(p(n).removeClass(jn),"ontouchstart"in document.documentElement&&p(document.body).children().off("mouseover",null,p.noop),this._activeTrigger[Un]=!1,this._activeTrigger[Wn]=!1,this._activeTrigger[Mn]=!1,p(this.tip).hasClass(Hn)){var r=m.getTransitionDurationFromElement(n);p(n).one(m.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){p(this.getTipElement()).addClass(Dn+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(p(t.querySelectorAll(Rn)),this.getTitle()),p(t).removeClass(Hn+" "+jn)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=bn(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?p(e).parent().is(t)||t.empty().append(e):t.text(p(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:m.isElement(this.config.container)?p(this.config.container):p(document).find(this.config.container)},t._getAttachment=function(t){return Nn[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)p(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Bn){var e=t===Mn?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Mn?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;p(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),p(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||p(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),p(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Wn:Mn]=!0),p(e.getTipElement()).hasClass(jn)||e._hoverState===Ln?e._hoverState=Ln:(clearTimeout(e._timeout),e._hoverState=Ln,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===Ln&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||p(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),p(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Wn:Mn]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=xn,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===xn&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=p(this.element).data();return Object.keys(e).forEach(function(t){-1!==An.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),m.typeCheckConfig(wn,t,this.constructor.DefaultType),t.sanitize&&(t.template=bn(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=p(this.getTipElement()),e=t.attr("class").match(In);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(p(t).removeClass(Hn),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=p(this).data(Cn),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),p(this).data(Cn,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return kn}},{key:"NAME",get:function(){return wn}},{key:"DATA_KEY",get:function(){return Cn}},{key:"Event",get:function(){return Pn}},{key:"EVENT_KEY",get:function(){return Tn}},{key:"DefaultType",get:function(){return On}}]),i}();p.fn[wn]=qn._jQueryInterface,p.fn[wn].Constructor=qn,p.fn[wn].noConflict=function(){return p.fn[wn]=Sn,qn._jQueryInterface};var Kn="popover",Qn="bs.popover",Vn="."+Qn,Yn=p.fn[Kn],zn="bs-popover",Xn=new RegExp("(^|\\s)"+zn+"\\S+","g"),Gn=l({},qn.Default,{placement:"right",trigger:"click",content:"",template:''}),$n=l({},qn.DefaultType,{content:"(string|element|function)"}),Jn="fade",Zn="show",ti=".popover-header",ei=".popover-body",ni={HIDE:"hide"+Vn,HIDDEN:"hidden"+Vn,SHOW:"show"+Vn,SHOWN:"shown"+Vn,INSERTED:"inserted"+Vn,CLICK:"click"+Vn,FOCUSIN:"focusin"+Vn,FOCUSOUT:"focusout"+Vn,MOUSEENTER:"mouseenter"+Vn,MOUSELEAVE:"mouseleave"+Vn},ii=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){p(this.getTipElement()).addClass(zn+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||p(this.config.template)[0],this.tip},o.setContent=function(){var t=p(this.getTipElement());this.setElementContent(t.find(ti),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(ei),e),t.removeClass(Jn+" "+Zn)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=p(this.getTipElement()),e=t.attr("class").match(Xn);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t= 0) {\n timeoutDuration = 1;\n break;\n }\n}\n\nfunction microtaskDebounce(fn) {\n var called = false;\n return function () {\n if (called) {\n return;\n }\n called = true;\n window.Promise.resolve().then(function () {\n called = false;\n fn();\n });\n };\n}\n\nfunction taskDebounce(fn) {\n var scheduled = false;\n return function () {\n if (!scheduled) {\n scheduled = true;\n setTimeout(function () {\n scheduled = false;\n fn();\n }, timeoutDuration);\n }\n };\n}\n\nvar supportsMicroTasks = isBrowser && window.Promise;\n\n/**\n* Create a debounced version of a method, that's asynchronously deferred\n* but called in the minimum time possible.\n*\n* @method\n* @memberof Popper.Utils\n* @argument {Function} fn\n* @returns {Function}\n*/\nvar debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;\n\n/**\n * Check if the given variable is a function\n * @method\n * @memberof Popper.Utils\n * @argument {Any} functionToCheck - variable to check\n * @returns {Boolean} answer to: is a function?\n */\nfunction isFunction(functionToCheck) {\n var getType = {};\n return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';\n}\n\n/**\n * Get CSS computed property of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Eement} element\n * @argument {String} property\n */\nfunction getStyleComputedProperty(element, property) {\n if (element.nodeType !== 1) {\n return [];\n }\n // NOTE: 1 DOM access here\n var css = getComputedStyle(element, null);\n return property ? css[property] : css;\n}\n\n/**\n * Returns the parentNode or the host of the element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} parent\n */\nfunction getParentNode(element) {\n if (element.nodeName === 'HTML') {\n return element;\n }\n return element.parentNode || element.host;\n}\n\n/**\n * Returns the scrolling parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} scroll parent\n */\nfunction getScrollParent(element) {\n // Return body, `getScroll` will take care to get the correct `scrollTop` from it\n if (!element) {\n return document.body;\n }\n\n switch (element.nodeName) {\n case 'HTML':\n case 'BODY':\n return element.ownerDocument.body;\n case '#document':\n return element.body;\n }\n\n // Firefox want us to check `-x` and `-y` variations as well\n\n var _getStyleComputedProp = getStyleComputedProperty(element),\n overflow = _getStyleComputedProp.overflow,\n overflowX = _getStyleComputedProp.overflowX,\n overflowY = _getStyleComputedProp.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {\n return element;\n }\n\n return getScrollParent(getParentNode(element));\n}\n\nvar isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);\nvar isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);\n\n/**\n * Determines if the browser is Internet Explorer\n * @method\n * @memberof Popper.Utils\n * @param {Number} version to check\n * @returns {Boolean} isIE\n */\nfunction isIE(version) {\n if (version === 11) {\n return isIE11;\n }\n if (version === 10) {\n return isIE10;\n }\n return isIE11 || isIE10;\n}\n\n/**\n * Returns the offset parent of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} offset parent\n */\nfunction getOffsetParent(element) {\n if (!element) {\n return document.documentElement;\n }\n\n var noOffsetParent = isIE(10) ? document.body : null;\n\n // NOTE: 1 DOM access here\n var offsetParent = element.offsetParent;\n // Skip hidden elements which don't have an offsetParent\n while (offsetParent === noOffsetParent && element.nextElementSibling) {\n offsetParent = (element = element.nextElementSibling).offsetParent;\n }\n\n var nodeName = offsetParent && offsetParent.nodeName;\n\n if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {\n return element ? element.ownerDocument.documentElement : document.documentElement;\n }\n\n // .offsetParent will return the closest TD or TABLE in case\n // no offsetParent is present, I hate this job...\n if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {\n return getOffsetParent(offsetParent);\n }\n\n return offsetParent;\n}\n\nfunction isOffsetContainer(element) {\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY') {\n return false;\n }\n return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;\n}\n\n/**\n * Finds the root node (document, shadowDOM root) of the given element\n * @method\n * @memberof Popper.Utils\n * @argument {Element} node\n * @returns {Element} root node\n */\nfunction getRoot(node) {\n if (node.parentNode !== null) {\n return getRoot(node.parentNode);\n }\n\n return node;\n}\n\n/**\n * Finds the offset parent common to the two provided nodes\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element1\n * @argument {Element} element2\n * @returns {Element} common offset parent\n */\nfunction findCommonOffsetParent(element1, element2) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {\n return document.documentElement;\n }\n\n // Here we make sure to give as \"start\" the element that comes first in the DOM\n var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;\n var start = order ? element1 : element2;\n var end = order ? element2 : element1;\n\n // Get common ancestor container\n var range = document.createRange();\n range.setStart(start, 0);\n range.setEnd(end, 0);\n var commonAncestorContainer = range.commonAncestorContainer;\n\n // Both nodes are inside #document\n\n if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {\n if (isOffsetContainer(commonAncestorContainer)) {\n return commonAncestorContainer;\n }\n\n return getOffsetParent(commonAncestorContainer);\n }\n\n // one of the nodes is inside shadowDOM, find which one\n var element1root = getRoot(element1);\n if (element1root.host) {\n return findCommonOffsetParent(element1root.host, element2);\n } else {\n return findCommonOffsetParent(element1, getRoot(element2).host);\n }\n}\n\n/**\n * Gets the scroll value of the given element in the given side (top and left)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {String} side `top` or `left`\n * @returns {number} amount of scrolled pixels\n */\nfunction getScroll(element) {\n var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';\n\n var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';\n var nodeName = element.nodeName;\n\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n var html = element.ownerDocument.documentElement;\n var scrollingElement = element.ownerDocument.scrollingElement || html;\n return scrollingElement[upperSide];\n }\n\n return element[upperSide];\n}\n\n/*\n * Sum or subtract the element scroll values (left and top) from a given rect object\n * @method\n * @memberof Popper.Utils\n * @param {Object} rect - Rect object you want to change\n * @param {HTMLElement} element - The element from the function reads the scroll values\n * @param {Boolean} subtract - set to true if you want to subtract the scroll values\n * @return {Object} rect - The modifier rect object\n */\nfunction includeScroll(rect, element) {\n var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n var modifier = subtract ? -1 : 1;\n rect.top += scrollTop * modifier;\n rect.bottom += scrollTop * modifier;\n rect.left += scrollLeft * modifier;\n rect.right += scrollLeft * modifier;\n return rect;\n}\n\n/*\n * Helper to detect borders of a given element\n * @method\n * @memberof Popper.Utils\n * @param {CSSStyleDeclaration} styles\n * Result of `getStyleComputedProperty` on the given element\n * @param {String} axis - `x` or `y`\n * @return {number} borders - The borders size of the given axis\n */\n\nfunction getBordersSize(styles, axis) {\n var sideA = axis === 'x' ? 'Left' : 'Top';\n var sideB = sideA === 'Left' ? 'Right' : 'Bottom';\n\n return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10);\n}\n\nfunction getSize(axis, body, html, computedStyle) {\n return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0);\n}\n\nfunction getWindowSizes() {\n var body = document.body;\n var html = document.documentElement;\n var computedStyle = isIE(10) && getComputedStyle(html);\n\n return {\n height: getSize('Height', body, html, computedStyle),\n width: getSize('Width', body, html, computedStyle)\n };\n}\n\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\n\n\n\n\nvar defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\n/**\n * Given element offsets, generate an output similar to getBoundingClientRect\n * @method\n * @memberof Popper.Utils\n * @argument {Object} offsets\n * @returns {Object} ClientRect like output\n */\nfunction getClientRect(offsets) {\n return _extends({}, offsets, {\n right: offsets.left + offsets.width,\n bottom: offsets.top + offsets.height\n });\n}\n\n/**\n * Get bounding client rect of given element\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} element\n * @return {Object} client rect\n */\nfunction getBoundingClientRect(element) {\n var rect = {};\n\n // IE10 10 FIX: Please, don't ask, the element isn't\n // considered in DOM in some circumstances...\n // This isn't reproducible in IE10 compatibility mode of IE11\n try {\n if (isIE(10)) {\n rect = element.getBoundingClientRect();\n var scrollTop = getScroll(element, 'top');\n var scrollLeft = getScroll(element, 'left');\n rect.top += scrollTop;\n rect.left += scrollLeft;\n rect.bottom += scrollTop;\n rect.right += scrollLeft;\n } else {\n rect = element.getBoundingClientRect();\n }\n } catch (e) {}\n\n var result = {\n left: rect.left,\n top: rect.top,\n width: rect.right - rect.left,\n height: rect.bottom - rect.top\n };\n\n // subtract scrollbar size from sizes\n var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {};\n var width = sizes.width || element.clientWidth || result.right - result.left;\n var height = sizes.height || element.clientHeight || result.bottom - result.top;\n\n var horizScrollbar = element.offsetWidth - width;\n var vertScrollbar = element.offsetHeight - height;\n\n // if an hypothetical scrollbar is detected, we must be sure it's not a `border`\n // we make this check conditional for performance reasons\n if (horizScrollbar || vertScrollbar) {\n var styles = getStyleComputedProperty(element);\n horizScrollbar -= getBordersSize(styles, 'x');\n vertScrollbar -= getBordersSize(styles, 'y');\n\n result.width -= horizScrollbar;\n result.height -= vertScrollbar;\n }\n\n return getClientRect(result);\n}\n\nfunction getOffsetRectRelativeToArbitraryNode(children, parent) {\n var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var isIE10 = isIE(10);\n var isHTML = parent.nodeName === 'HTML';\n var childrenRect = getBoundingClientRect(children);\n var parentRect = getBoundingClientRect(parent);\n var scrollParent = getScrollParent(children);\n\n var styles = getStyleComputedProperty(parent);\n var borderTopWidth = parseFloat(styles.borderTopWidth, 10);\n var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10);\n\n // In cases where the parent is fixed, we must ignore negative scroll in offset calc\n if (fixedPosition && parent.nodeName === 'HTML') {\n parentRect.top = Math.max(parentRect.top, 0);\n parentRect.left = Math.max(parentRect.left, 0);\n }\n var offsets = getClientRect({\n top: childrenRect.top - parentRect.top - borderTopWidth,\n left: childrenRect.left - parentRect.left - borderLeftWidth,\n width: childrenRect.width,\n height: childrenRect.height\n });\n offsets.marginTop = 0;\n offsets.marginLeft = 0;\n\n // Subtract margins of documentElement in case it's being used as parent\n // we do this only on HTML because it's the only element that behaves\n // differently when margins are applied to it. The margins are included in\n // the box of the documentElement, in the other cases not.\n if (!isIE10 && isHTML) {\n var marginTop = parseFloat(styles.marginTop, 10);\n var marginLeft = parseFloat(styles.marginLeft, 10);\n\n offsets.top -= borderTopWidth - marginTop;\n offsets.bottom -= borderTopWidth - marginTop;\n offsets.left -= borderLeftWidth - marginLeft;\n offsets.right -= borderLeftWidth - marginLeft;\n\n // Attach marginTop and marginLeft because in some circumstances we may need them\n offsets.marginTop = marginTop;\n offsets.marginLeft = marginLeft;\n }\n\n if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {\n offsets = includeScroll(offsets, parent);\n }\n\n return offsets;\n}\n\nfunction getViewportOffsetRectRelativeToArtbitraryNode(element) {\n var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var html = element.ownerDocument.documentElement;\n var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);\n var width = Math.max(html.clientWidth, window.innerWidth || 0);\n var height = Math.max(html.clientHeight, window.innerHeight || 0);\n\n var scrollTop = !excludeScroll ? getScroll(html) : 0;\n var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;\n\n var offset = {\n top: scrollTop - relativeOffset.top + relativeOffset.marginTop,\n left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,\n width: width,\n height: height\n };\n\n return getClientRect(offset);\n}\n\n/**\n * Check if the given element is fixed or is inside a fixed parent\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @argument {Element} customContainer\n * @returns {Boolean} answer to \"isFixed?\"\n */\nfunction isFixed(element) {\n var nodeName = element.nodeName;\n if (nodeName === 'BODY' || nodeName === 'HTML') {\n return false;\n }\n if (getStyleComputedProperty(element, 'position') === 'fixed') {\n return true;\n }\n return isFixed(getParentNode(element));\n}\n\n/**\n * Finds the first parent of an element that has a transformed property defined\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Element} first transformed parent or documentElement\n */\n\nfunction getFixedPositionOffsetParent(element) {\n // This check is needed to avoid errors in case one of the elements isn't defined for any reason\n if (!element || !element.parentElement || isIE()) {\n return document.documentElement;\n }\n var el = element.parentElement;\n while (el && getStyleComputedProperty(el, 'transform') === 'none') {\n el = el.parentElement;\n }\n return el || document.documentElement;\n}\n\n/**\n * Computed the boundaries limits and return them\n * @method\n * @memberof Popper.Utils\n * @param {HTMLElement} popper\n * @param {HTMLElement} reference\n * @param {number} padding\n * @param {HTMLElement} boundariesElement - Element used to define the boundaries\n * @param {Boolean} fixedPosition - Is in fixed position mode\n * @returns {Object} Coordinates of the boundaries\n */\nfunction getBoundaries(popper, reference, padding, boundariesElement) {\n var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n\n // NOTE: 1 DOM access here\n\n var boundaries = { top: 0, left: 0 };\n var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference);\n\n // Handle viewport case\n if (boundariesElement === 'viewport') {\n boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);\n } else {\n // Handle other cases based on DOM element used as boundaries\n var boundariesNode = void 0;\n if (boundariesElement === 'scrollParent') {\n boundariesNode = getScrollParent(getParentNode(reference));\n if (boundariesNode.nodeName === 'BODY') {\n boundariesNode = popper.ownerDocument.documentElement;\n }\n } else if (boundariesElement === 'window') {\n boundariesNode = popper.ownerDocument.documentElement;\n } else {\n boundariesNode = boundariesElement;\n }\n\n var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);\n\n // In case of HTML, we need a different computation\n if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {\n var _getWindowSizes = getWindowSizes(),\n height = _getWindowSizes.height,\n width = _getWindowSizes.width;\n\n boundaries.top += offsets.top - offsets.marginTop;\n boundaries.bottom = height + offsets.top;\n boundaries.left += offsets.left - offsets.marginLeft;\n boundaries.right = width + offsets.left;\n } else {\n // for all the other DOM elements, this one is good\n boundaries = offsets;\n }\n }\n\n // Add paddings\n boundaries.left += padding;\n boundaries.top += padding;\n boundaries.right -= padding;\n boundaries.bottom -= padding;\n\n return boundaries;\n}\n\nfunction getArea(_ref) {\n var width = _ref.width,\n height = _ref.height;\n\n return width * height;\n}\n\n/**\n * Utility used to transform the `auto` placement to the placement with more\n * available space.\n * @method\n * @memberof Popper.Utils\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {\n var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n\n if (placement.indexOf('auto') === -1) {\n return placement;\n }\n\n var boundaries = getBoundaries(popper, reference, padding, boundariesElement);\n\n var rects = {\n top: {\n width: boundaries.width,\n height: refRect.top - boundaries.top\n },\n right: {\n width: boundaries.right - refRect.right,\n height: boundaries.height\n },\n bottom: {\n width: boundaries.width,\n height: boundaries.bottom - refRect.bottom\n },\n left: {\n width: refRect.left - boundaries.left,\n height: boundaries.height\n }\n };\n\n var sortedAreas = Object.keys(rects).map(function (key) {\n return _extends({\n key: key\n }, rects[key], {\n area: getArea(rects[key])\n });\n }).sort(function (a, b) {\n return b.area - a.area;\n });\n\n var filteredAreas = sortedAreas.filter(function (_ref2) {\n var width = _ref2.width,\n height = _ref2.height;\n return width >= popper.clientWidth && height >= popper.clientHeight;\n });\n\n var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;\n\n var variation = placement.split('-')[1];\n\n return computedPlacement + (variation ? '-' + variation : '');\n}\n\n/**\n * Get offsets to the reference element\n * @method\n * @memberof Popper.Utils\n * @param {Object} state\n * @param {Element} popper - the popper element\n * @param {Element} reference - the reference element (the popper will be relative to this)\n * @param {Element} fixedPosition - is in fixed position mode\n * @returns {Object} An object containing the offsets which will be applied to the popper\n */\nfunction getReferenceOffsets(state, popper, reference) {\n var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n\n var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference);\n return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);\n}\n\n/**\n * Get the outer sizes of the given element (offset size + margins)\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element\n * @returns {Object} object containing width and height properties\n */\nfunction getOuterSizes(element) {\n var styles = getComputedStyle(element);\n var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);\n var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);\n var result = {\n width: element.offsetWidth + y,\n height: element.offsetHeight + x\n };\n return result;\n}\n\n/**\n * Get the opposite placement of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement\n * @returns {String} flipped placement\n */\nfunction getOppositePlacement(placement) {\n var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}\n\n/**\n * Get offsets to the popper\n * @method\n * @memberof Popper.Utils\n * @param {Object} position - CSS position the Popper will get applied\n * @param {HTMLElement} popper - the popper element\n * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)\n * @param {String} placement - one of the valid placement options\n * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper\n */\nfunction getPopperOffsets(popper, referenceOffsets, placement) {\n placement = placement.split('-')[0];\n\n // Get popper node sizes\n var popperRect = getOuterSizes(popper);\n\n // Add position, width and height to our offsets object\n var popperOffsets = {\n width: popperRect.width,\n height: popperRect.height\n };\n\n // depending by the popper placement we have to compute its offsets slightly differently\n var isHoriz = ['right', 'left'].indexOf(placement) !== -1;\n var mainSide = isHoriz ? 'top' : 'left';\n var secondarySide = isHoriz ? 'left' : 'top';\n var measurement = isHoriz ? 'height' : 'width';\n var secondaryMeasurement = !isHoriz ? 'height' : 'width';\n\n popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;\n if (placement === secondarySide) {\n popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];\n } else {\n popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];\n }\n\n return popperOffsets;\n}\n\n/**\n * Mimics the `find` method of Array\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction find(arr, check) {\n // use native find if supported\n if (Array.prototype.find) {\n return arr.find(check);\n }\n\n // use `filter` to obtain the same behavior of `find`\n return arr.filter(check)[0];\n}\n\n/**\n * Return the index of the matching object\n * @method\n * @memberof Popper.Utils\n * @argument {Array} arr\n * @argument prop\n * @argument value\n * @returns index or -1\n */\nfunction findIndex(arr, prop, value) {\n // use native findIndex if supported\n if (Array.prototype.findIndex) {\n return arr.findIndex(function (cur) {\n return cur[prop] === value;\n });\n }\n\n // use `find` + `indexOf` if `findIndex` isn't supported\n var match = find(arr, function (obj) {\n return obj[prop] === value;\n });\n return arr.indexOf(match);\n}\n\n/**\n * Loop trough the list of modifiers and run them in order,\n * each of them will then edit the data object.\n * @method\n * @memberof Popper.Utils\n * @param {dataObject} data\n * @param {Array} modifiers\n * @param {String} ends - Optional modifier name used as stopper\n * @returns {dataObject}\n */\nfunction runModifiers(modifiers, data, ends) {\n var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));\n\n modifiersToRun.forEach(function (modifier) {\n if (modifier['function']) {\n // eslint-disable-line dot-notation\n console.warn('`modifier.function` is deprecated, use `modifier.fn`!');\n }\n var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation\n if (modifier.enabled && isFunction(fn)) {\n // Add properties to offsets to make them a complete clientRect object\n // we do this before each modifier to make sure the previous one doesn't\n // mess with these values\n data.offsets.popper = getClientRect(data.offsets.popper);\n data.offsets.reference = getClientRect(data.offsets.reference);\n\n data = fn(data, modifier);\n }\n });\n\n return data;\n}\n\n/**\n * Updates the position of the popper, computing the new offsets and applying\n * the new style.
\n * Prefer `scheduleUpdate` over `update` because of performance reasons.\n * @method\n * @memberof Popper\n */\nfunction update() {\n // if popper is destroyed, don't perform any further update\n if (this.state.isDestroyed) {\n return;\n }\n\n var data = {\n instance: this,\n styles: {},\n arrowStyles: {},\n attributes: {},\n flipped: false,\n offsets: {}\n };\n\n // compute reference element offsets\n data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);\n\n // store the computed placement inside `originalPlacement`\n data.originalPlacement = data.placement;\n\n data.positionFixed = this.options.positionFixed;\n\n // compute the popper offsets\n data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);\n\n data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';\n\n // run the modifiers\n data = runModifiers(this.modifiers, data);\n\n // the first `update` will call `onCreate` callback\n // the other ones will call `onUpdate` callback\n if (!this.state.isCreated) {\n this.state.isCreated = true;\n this.options.onCreate(data);\n } else {\n this.options.onUpdate(data);\n }\n}\n\n/**\n * Helper used to know if the given modifier is enabled.\n * @method\n * @memberof Popper.Utils\n * @returns {Boolean}\n */\nfunction isModifierEnabled(modifiers, modifierName) {\n return modifiers.some(function (_ref) {\n var name = _ref.name,\n enabled = _ref.enabled;\n return enabled && name === modifierName;\n });\n}\n\n/**\n * Get the prefixed supported property name\n * @method\n * @memberof Popper.Utils\n * @argument {String} property (camelCase)\n * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)\n */\nfunction getSupportedPropertyName(property) {\n var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];\n var upperProp = property.charAt(0).toUpperCase() + property.slice(1);\n\n for (var i = 0; i < prefixes.length; i++) {\n var prefix = prefixes[i];\n var toCheck = prefix ? '' + prefix + upperProp : property;\n if (typeof document.body.style[toCheck] !== 'undefined') {\n return toCheck;\n }\n }\n return null;\n}\n\n/**\n * Destroy the popper\n * @method\n * @memberof Popper\n */\nfunction destroy() {\n this.state.isDestroyed = true;\n\n // touch DOM only if `applyStyle` modifier is enabled\n if (isModifierEnabled(this.modifiers, 'applyStyle')) {\n this.popper.removeAttribute('x-placement');\n this.popper.style.position = '';\n this.popper.style.top = '';\n this.popper.style.left = '';\n this.popper.style.right = '';\n this.popper.style.bottom = '';\n this.popper.style.willChange = '';\n this.popper.style[getSupportedPropertyName('transform')] = '';\n }\n\n this.disableEventListeners();\n\n // remove the popper if user explicity asked for the deletion on destroy\n // do not use `remove` because IE11 doesn't support it\n if (this.options.removeOnDestroy) {\n this.popper.parentNode.removeChild(this.popper);\n }\n return this;\n}\n\n/**\n * Get the window associated with the element\n * @argument {Element} element\n * @returns {Window}\n */\nfunction getWindow(element) {\n var ownerDocument = element.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView : window;\n}\n\nfunction attachToScrollParents(scrollParent, event, callback, scrollParents) {\n var isBody = scrollParent.nodeName === 'BODY';\n var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;\n target.addEventListener(event, callback, { passive: true });\n\n if (!isBody) {\n attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);\n }\n scrollParents.push(target);\n}\n\n/**\n * Setup needed event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction setupEventListeners(reference, options, state, updateBound) {\n // Resize event listener on window\n state.updateBound = updateBound;\n getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });\n\n // Scroll event listener on scroll parents\n var scrollElement = getScrollParent(reference);\n attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);\n state.scrollElement = scrollElement;\n state.eventsEnabled = true;\n\n return state;\n}\n\n/**\n * It will add resize/scroll events and start recalculating\n * position of the popper element when they are triggered.\n * @method\n * @memberof Popper\n */\nfunction enableEventListeners() {\n if (!this.state.eventsEnabled) {\n this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);\n }\n}\n\n/**\n * Remove event listeners used to update the popper position\n * @method\n * @memberof Popper.Utils\n * @private\n */\nfunction removeEventListeners(reference, state) {\n // Remove resize event listener on window\n getWindow(reference).removeEventListener('resize', state.updateBound);\n\n // Remove scroll event listener on scroll parents\n state.scrollParents.forEach(function (target) {\n target.removeEventListener('scroll', state.updateBound);\n });\n\n // Reset state\n state.updateBound = null;\n state.scrollParents = [];\n state.scrollElement = null;\n state.eventsEnabled = false;\n return state;\n}\n\n/**\n * It will remove resize/scroll events and won't recalculate popper position\n * when they are triggered. It also won't trigger onUpdate callback anymore,\n * unless you call `update` method manually.\n * @method\n * @memberof Popper\n */\nfunction disableEventListeners() {\n if (this.state.eventsEnabled) {\n cancelAnimationFrame(this.scheduleUpdate);\n this.state = removeEventListeners(this.reference, this.state);\n }\n}\n\n/**\n * Tells if a given input is a number\n * @method\n * @memberof Popper.Utils\n * @param {*} input to check\n * @return {Boolean}\n */\nfunction isNumeric(n) {\n return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);\n}\n\n/**\n * Set the style to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the style to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setStyles(element, styles) {\n Object.keys(styles).forEach(function (prop) {\n var unit = '';\n // add unit if the value is numeric and is one of the following\n if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {\n unit = 'px';\n }\n element.style[prop] = styles[prop] + unit;\n });\n}\n\n/**\n * Set the attributes to the given popper\n * @method\n * @memberof Popper.Utils\n * @argument {Element} element - Element to apply the attributes to\n * @argument {Object} styles\n * Object with a list of properties and values which will be applied to the element\n */\nfunction setAttributes(element, attributes) {\n Object.keys(attributes).forEach(function (prop) {\n var value = attributes[prop];\n if (value !== false) {\n element.setAttribute(prop, attributes[prop]);\n } else {\n element.removeAttribute(prop);\n }\n });\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} data.styles - List of style properties - values to apply to popper element\n * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The same data object\n */\nfunction applyStyle(data) {\n // any property present in `data.styles` will be applied to the popper,\n // in this way we can make the 3rd party modifiers add custom styles to it\n // Be aware, modifiers could override the properties defined in the previous\n // lines of this modifier!\n setStyles(data.instance.popper, data.styles);\n\n // any property present in `data.attributes` will be applied to the popper,\n // they will be set as HTML attributes of the element\n setAttributes(data.instance.popper, data.attributes);\n\n // if arrowElement is defined and arrowStyles has some properties\n if (data.arrowElement && Object.keys(data.arrowStyles).length) {\n setStyles(data.arrowElement, data.arrowStyles);\n }\n\n return data;\n}\n\n/**\n * Set the x-placement attribute before everything else because it could be used\n * to add margins to the popper margins needs to be calculated to get the\n * correct popper offsets.\n * @method\n * @memberof Popper.modifiers\n * @param {HTMLElement} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper\n * @param {Object} options - Popper.js options\n */\nfunction applyStyleOnLoad(reference, popper, options, modifierOptions, state) {\n // compute reference element offsets\n var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);\n\n // compute auto placement, store placement inside the data object,\n // modifiers will be able to edit `placement` if needed\n // and refer to originalPlacement to know the original value\n var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);\n\n popper.setAttribute('x-placement', placement);\n\n // Apply `position` to popper before anything else because\n // without the position applied we can't guarantee correct computations\n setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });\n\n return options;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction computeStyle(data, options) {\n var x = options.x,\n y = options.y;\n var popper = data.offsets.popper;\n\n // Remove this legacy support in Popper.js v2\n\n var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'applyStyle';\n }).gpuAcceleration;\n if (legacyGpuAccelerationOption !== undefined) {\n console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');\n }\n var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;\n\n var offsetParent = getOffsetParent(data.instance.popper);\n var offsetParentRect = getBoundingClientRect(offsetParent);\n\n // Styles\n var styles = {\n position: popper.position\n };\n\n // Avoid blurry text by using full pixel integers.\n // For pixel-perfect positioning, top/bottom prefers rounded\n // values, while left/right prefers floored values.\n var offsets = {\n left: Math.floor(popper.left),\n top: Math.round(popper.top),\n bottom: Math.round(popper.bottom),\n right: Math.floor(popper.right)\n };\n\n var sideA = x === 'bottom' ? 'top' : 'bottom';\n var sideB = y === 'right' ? 'left' : 'right';\n\n // if gpuAcceleration is set to `true` and transform is supported,\n // we use `translate3d` to apply the position to the popper we\n // automatically use the supported prefixed version if needed\n var prefixedProperty = getSupportedPropertyName('transform');\n\n // now, let's make a step back and look at this code closely (wtf?)\n // If the content of the popper grows once it's been positioned, it\n // may happen that the popper gets misplaced because of the new content\n // overflowing its reference element\n // To avoid this problem, we provide two options (x and y), which allow\n // the consumer to define the offset origin.\n // If we position a popper on top of a reference element, we can set\n // `x` to `top` to make the popper grow towards its top instead of\n // its bottom.\n var left = void 0,\n top = void 0;\n if (sideA === 'bottom') {\n top = -offsetParentRect.height + offsets.bottom;\n } else {\n top = offsets.top;\n }\n if (sideB === 'right') {\n left = -offsetParentRect.width + offsets.right;\n } else {\n left = offsets.left;\n }\n if (gpuAcceleration && prefixedProperty) {\n styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';\n styles[sideA] = 0;\n styles[sideB] = 0;\n styles.willChange = 'transform';\n } else {\n // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties\n var invertTop = sideA === 'bottom' ? -1 : 1;\n var invertLeft = sideB === 'right' ? -1 : 1;\n styles[sideA] = top * invertTop;\n styles[sideB] = left * invertLeft;\n styles.willChange = sideA + ', ' + sideB;\n }\n\n // Attributes\n var attributes = {\n 'x-placement': data.placement\n };\n\n // Update `data` attributes, styles and arrowStyles\n data.attributes = _extends({}, attributes, data.attributes);\n data.styles = _extends({}, styles, data.styles);\n data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);\n\n return data;\n}\n\n/**\n * Helper used to know if the given modifier depends from another one.
\n * It checks if the needed modifier is listed and enabled.\n * @method\n * @memberof Popper.Utils\n * @param {Array} modifiers - list of modifiers\n * @param {String} requestingName - name of requesting modifier\n * @param {String} requestedName - name of requested modifier\n * @returns {Boolean}\n */\nfunction isModifierRequired(modifiers, requestingName, requestedName) {\n var requesting = find(modifiers, function (_ref) {\n var name = _ref.name;\n return name === requestingName;\n });\n\n var isRequired = !!requesting && modifiers.some(function (modifier) {\n return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;\n });\n\n if (!isRequired) {\n var _requesting = '`' + requestingName + '`';\n var requested = '`' + requestedName + '`';\n console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');\n }\n return isRequired;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction arrow(data, options) {\n var _data$offsets$arrow;\n\n // arrow depends on keepTogether in order to work\n if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {\n return data;\n }\n\n var arrowElement = options.element;\n\n // if arrowElement is a string, suppose it's a CSS selector\n if (typeof arrowElement === 'string') {\n arrowElement = data.instance.popper.querySelector(arrowElement);\n\n // if arrowElement is not found, don't run the modifier\n if (!arrowElement) {\n return data;\n }\n } else {\n // if the arrowElement isn't a query selector we must check that the\n // provided DOM node is child of its popper node\n if (!data.instance.popper.contains(arrowElement)) {\n console.warn('WARNING: `arrow.element` must be child of its popper element!');\n return data;\n }\n }\n\n var placement = data.placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isVertical = ['left', 'right'].indexOf(placement) !== -1;\n\n var len = isVertical ? 'height' : 'width';\n var sideCapitalized = isVertical ? 'Top' : 'Left';\n var side = sideCapitalized.toLowerCase();\n var altSide = isVertical ? 'left' : 'top';\n var opSide = isVertical ? 'bottom' : 'right';\n var arrowElementSize = getOuterSizes(arrowElement)[len];\n\n //\n // extends keepTogether behavior making sure the popper and its\n // reference have enough pixels in conjuction\n //\n\n // top/left side\n if (reference[opSide] - arrowElementSize < popper[side]) {\n data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);\n }\n // bottom/right side\n if (reference[side] + arrowElementSize > popper[opSide]) {\n data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];\n }\n data.offsets.popper = getClientRect(data.offsets.popper);\n\n // compute center of the popper\n var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;\n\n // Compute the sideValue using the updated popper offsets\n // take popper margin in account because we don't have this info available\n var css = getStyleComputedProperty(data.instance.popper);\n var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10);\n var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10);\n var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;\n\n // prevent arrowElement from being placed not contiguously to its popper\n sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);\n\n data.arrowElement = arrowElement;\n data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);\n\n return data;\n}\n\n/**\n * Get the opposite placement variation of the given one\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement variation\n * @returns {String} flipped placement variation\n */\nfunction getOppositeVariation(variation) {\n if (variation === 'end') {\n return 'start';\n } else if (variation === 'start') {\n return 'end';\n }\n return variation;\n}\n\n/**\n * List of accepted placements to use as values of the `placement` option.
\n * Valid placements are:\n * - `auto`\n * - `top`\n * - `right`\n * - `bottom`\n * - `left`\n *\n * Each placement can have a variation from this list:\n * - `-start`\n * - `-end`\n *\n * Variations are interpreted easily if you think of them as the left to right\n * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`\n * is right.
\n * Vertically (`left` and `right`), `start` is top and `end` is bottom.\n *\n * Some valid examples are:\n * - `top-end` (on top of reference, right aligned)\n * - `right-start` (on right of reference, top aligned)\n * - `bottom` (on bottom, centered)\n * - `auto-right` (on the side with more space available, alignment depends by placement)\n *\n * @static\n * @type {Array}\n * @enum {String}\n * @readonly\n * @method placements\n * @memberof Popper\n */\nvar placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];\n\n// Get rid of `auto` `auto-start` and `auto-end`\nvar validPlacements = placements.slice(3);\n\n/**\n * Given an initial placement, returns all the subsequent placements\n * clockwise (or counter-clockwise).\n *\n * @method\n * @memberof Popper.Utils\n * @argument {String} placement - A valid placement (it accepts variations)\n * @argument {Boolean} counter - Set to true to walk the placements counterclockwise\n * @returns {Array} placements including their variations\n */\nfunction clockwise(placement) {\n var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var index = validPlacements.indexOf(placement);\n var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));\n return counter ? arr.reverse() : arr;\n}\n\nvar BEHAVIORS = {\n FLIP: 'flip',\n CLOCKWISE: 'clockwise',\n COUNTERCLOCKWISE: 'counterclockwise'\n};\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction flip(data, options) {\n // if `inner` modifier is enabled, we can't use the `flip` modifier\n if (isModifierEnabled(data.instance.modifiers, 'inner')) {\n return data;\n }\n\n if (data.flipped && data.placement === data.originalPlacement) {\n // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides\n return data;\n }\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);\n\n var placement = data.placement.split('-')[0];\n var placementOpposite = getOppositePlacement(placement);\n var variation = data.placement.split('-')[1] || '';\n\n var flipOrder = [];\n\n switch (options.behavior) {\n case BEHAVIORS.FLIP:\n flipOrder = [placement, placementOpposite];\n break;\n case BEHAVIORS.CLOCKWISE:\n flipOrder = clockwise(placement);\n break;\n case BEHAVIORS.COUNTERCLOCKWISE:\n flipOrder = clockwise(placement, true);\n break;\n default:\n flipOrder = options.behavior;\n }\n\n flipOrder.forEach(function (step, index) {\n if (placement !== step || flipOrder.length === index + 1) {\n return data;\n }\n\n placement = data.placement.split('-')[0];\n placementOpposite = getOppositePlacement(placement);\n\n var popperOffsets = data.offsets.popper;\n var refOffsets = data.offsets.reference;\n\n // using floor because the reference offsets may contain decimals we are not going to consider here\n var floor = Math.floor;\n var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);\n\n var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);\n var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);\n var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);\n var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);\n\n var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;\n\n // flip the variation if required\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);\n\n if (overlapsRef || overflowsBoundaries || flippedVariation) {\n // this boolean to detect any flip loop\n data.flipped = true;\n\n if (overlapsRef || overflowsBoundaries) {\n placement = flipOrder[index + 1];\n }\n\n if (flippedVariation) {\n variation = getOppositeVariation(variation);\n }\n\n data.placement = placement + (variation ? '-' + variation : '');\n\n // this object contains `position`, we want to preserve it along with\n // any additional property we may add in the future\n data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));\n\n data = runModifiers(data.instance.modifiers, data, 'flip');\n }\n });\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction keepTogether(data) {\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var placement = data.placement.split('-')[0];\n var floor = Math.floor;\n var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;\n var side = isVertical ? 'right' : 'bottom';\n var opSide = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n if (popper[side] < floor(reference[opSide])) {\n data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];\n }\n if (popper[opSide] > floor(reference[side])) {\n data.offsets.popper[opSide] = floor(reference[side]);\n }\n\n return data;\n}\n\n/**\n * Converts a string containing value + unit into a px value number\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} str - Value + unit string\n * @argument {String} measurement - `height` or `width`\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @returns {Number|String}\n * Value in pixels, or original string if no values were extracted\n */\nfunction toValue(str, measurement, popperOffsets, referenceOffsets) {\n // separate value from unit\n var split = str.match(/((?:\\-|\\+)?\\d*\\.?\\d*)(.*)/);\n var value = +split[1];\n var unit = split[2];\n\n // If it's not a number it's an operator, I guess\n if (!value) {\n return str;\n }\n\n if (unit.indexOf('%') === 0) {\n var element = void 0;\n switch (unit) {\n case '%p':\n element = popperOffsets;\n break;\n case '%':\n case '%r':\n default:\n element = referenceOffsets;\n }\n\n var rect = getClientRect(element);\n return rect[measurement] / 100 * value;\n } else if (unit === 'vh' || unit === 'vw') {\n // if is a vh or vw, we calculate the size based on the viewport\n var size = void 0;\n if (unit === 'vh') {\n size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n } else {\n size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n }\n return size / 100 * value;\n } else {\n // if is an explicit pixel unit, we get rid of the unit and keep the value\n // if is an implicit unit, it's px, and we return just the value\n return value;\n }\n}\n\n/**\n * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.\n * @function\n * @memberof {modifiers~offset}\n * @private\n * @argument {String} offset\n * @argument {Object} popperOffsets\n * @argument {Object} referenceOffsets\n * @argument {String} basePlacement\n * @returns {Array} a two cells array with x and y offsets in numbers\n */\nfunction parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {\n var offsets = [0, 0];\n\n // Use height if placement is left or right and index is 0 otherwise use width\n // in this way the first offset will use an axis and the second one\n // will use the other one\n var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;\n\n // Split the offset string to obtain a list of values and operands\n // The regex addresses values with the plus or minus sign in front (+10, -20, etc)\n var fragments = offset.split(/(\\+|\\-)/).map(function (frag) {\n return frag.trim();\n });\n\n // Detect if the offset string contains a pair of values or a single one\n // they could be separated by comma or space\n var divider = fragments.indexOf(find(fragments, function (frag) {\n return frag.search(/,|\\s/) !== -1;\n }));\n\n if (fragments[divider] && fragments[divider].indexOf(',') === -1) {\n console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');\n }\n\n // If divider is found, we divide the list of values and operands to divide\n // them by ofset X and Y.\n var splitRegex = /\\s*,\\s*|\\s+/;\n var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];\n\n // Convert the values with units to absolute pixels to allow our computations\n ops = ops.map(function (op, index) {\n // Most of the units rely on the orientation of the popper\n var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';\n var mergeWithPrevious = false;\n return op\n // This aggregates any `+` or `-` sign that aren't considered operators\n // e.g.: 10 + +5 => [10, +, +5]\n .reduce(function (a, b) {\n if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {\n a[a.length - 1] = b;\n mergeWithPrevious = true;\n return a;\n } else if (mergeWithPrevious) {\n a[a.length - 1] += b;\n mergeWithPrevious = false;\n return a;\n } else {\n return a.concat(b);\n }\n }, [])\n // Here we convert the string values into number values (in px)\n .map(function (str) {\n return toValue(str, measurement, popperOffsets, referenceOffsets);\n });\n });\n\n // Loop trough the offsets arrays and execute the operations\n ops.forEach(function (op, index) {\n op.forEach(function (frag, index2) {\n if (isNumeric(frag)) {\n offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);\n }\n });\n });\n return offsets;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @argument {Number|String} options.offset=0\n * The offset value as described in the modifier description\n * @returns {Object} The data object, properly modified\n */\nfunction offset(data, _ref) {\n var offset = _ref.offset;\n var placement = data.placement,\n _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var basePlacement = placement.split('-')[0];\n\n var offsets = void 0;\n if (isNumeric(+offset)) {\n offsets = [+offset, 0];\n } else {\n offsets = parseOffset(offset, popper, reference, basePlacement);\n }\n\n if (basePlacement === 'left') {\n popper.top += offsets[0];\n popper.left -= offsets[1];\n } else if (basePlacement === 'right') {\n popper.top += offsets[0];\n popper.left += offsets[1];\n } else if (basePlacement === 'top') {\n popper.left += offsets[0];\n popper.top -= offsets[1];\n } else if (basePlacement === 'bottom') {\n popper.left += offsets[0];\n popper.top += offsets[1];\n }\n\n data.popper = popper;\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction preventOverflow(data, options) {\n var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);\n\n // If offsetParent is the reference element, we really want to\n // go one step up and use the next offsetParent as reference to\n // avoid to make this modifier completely useless and look like broken\n if (data.instance.reference === boundariesElement) {\n boundariesElement = getOffsetParent(boundariesElement);\n }\n\n // NOTE: DOM access here\n // resets the popper's position so that the document size can be calculated excluding\n // the size of the popper element itself\n var transformProp = getSupportedPropertyName('transform');\n var popperStyles = data.instance.popper.style; // assignment to help minification\n var top = popperStyles.top,\n left = popperStyles.left,\n transform = popperStyles[transformProp];\n\n popperStyles.top = '';\n popperStyles.left = '';\n popperStyles[transformProp] = '';\n\n var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);\n\n // NOTE: DOM access here\n // restores the original style properties after the offsets have been computed\n popperStyles.top = top;\n popperStyles.left = left;\n popperStyles[transformProp] = transform;\n\n options.boundaries = boundaries;\n\n var order = options.priority;\n var popper = data.offsets.popper;\n\n var check = {\n primary: function primary(placement) {\n var value = popper[placement];\n if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {\n value = Math.max(popper[placement], boundaries[placement]);\n }\n return defineProperty({}, placement, value);\n },\n secondary: function secondary(placement) {\n var mainSide = placement === 'right' ? 'left' : 'top';\n var value = popper[mainSide];\n if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {\n value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));\n }\n return defineProperty({}, mainSide, value);\n }\n };\n\n order.forEach(function (placement) {\n var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';\n popper = _extends({}, popper, check[side](placement));\n });\n\n data.offsets.popper = popper;\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction shift(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var shiftvariation = placement.split('-')[1];\n\n // if shift shiftvariation is specified, run the modifier\n if (shiftvariation) {\n var _data$offsets = data.offsets,\n reference = _data$offsets.reference,\n popper = _data$offsets.popper;\n\n var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;\n var side = isVertical ? 'left' : 'top';\n var measurement = isVertical ? 'width' : 'height';\n\n var shiftOffsets = {\n start: defineProperty({}, side, reference[side]),\n end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])\n };\n\n data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by update method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction hide(data) {\n if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {\n return data;\n }\n\n var refRect = data.offsets.reference;\n var bound = find(data.instance.modifiers, function (modifier) {\n return modifier.name === 'preventOverflow';\n }).boundaries;\n\n if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === true) {\n return data;\n }\n\n data.hide = true;\n data.attributes['x-out-of-boundaries'] = '';\n } else {\n // Avoid unnecessary DOM access if visibility hasn't changed\n if (data.hide === false) {\n return data;\n }\n\n data.hide = false;\n data.attributes['x-out-of-boundaries'] = false;\n }\n\n return data;\n}\n\n/**\n * @function\n * @memberof Modifiers\n * @argument {Object} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {Object} The data object, properly modified\n */\nfunction inner(data) {\n var placement = data.placement;\n var basePlacement = placement.split('-')[0];\n var _data$offsets = data.offsets,\n popper = _data$offsets.popper,\n reference = _data$offsets.reference;\n\n var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;\n\n var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;\n\n popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);\n\n data.placement = getOppositePlacement(placement);\n data.offsets.popper = getClientRect(popper);\n\n return data;\n}\n\n/**\n * Modifier function, each modifier can have a function of this type assigned\n * to its `fn` property.
\n * These functions will be called on each update, this means that you must\n * make sure they are performant enough to avoid performance bottlenecks.\n *\n * @function ModifierFn\n * @argument {dataObject} data - The data object generated by `update` method\n * @argument {Object} options - Modifiers configuration and options\n * @returns {dataObject} The data object, properly modified\n */\n\n/**\n * Modifiers are plugins used to alter the behavior of your poppers.
\n * Popper.js uses a set of 9 modifiers to provide all the basic functionalities\n * needed by the library.\n *\n * Usually you don't want to override the `order`, `fn` and `onLoad` props.\n * All the other properties are configurations that could be tweaked.\n * @namespace modifiers\n */\nvar modifiers = {\n /**\n * Modifier used to shift the popper on the start or end of its reference\n * element.
\n * It will read the variation of the `placement` property.
\n * It can be one either `-end` or `-start`.\n * @memberof modifiers\n * @inner\n */\n shift: {\n /** @prop {number} order=100 - Index used to define the order of execution */\n order: 100,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: shift\n },\n\n /**\n * The `offset` modifier can shift your popper on both its axis.\n *\n * It accepts the following units:\n * - `px` or unitless, interpreted as pixels\n * - `%` or `%r`, percentage relative to the length of the reference element\n * - `%p`, percentage relative to the length of the popper element\n * - `vw`, CSS viewport width unit\n * - `vh`, CSS viewport height unit\n *\n * For length is intended the main axis relative to the placement of the popper.
\n * This means that if the placement is `top` or `bottom`, the length will be the\n * `width`. In case of `left` or `right`, it will be the height.\n *\n * You can provide a single value (as `Number` or `String`), or a pair of values\n * as `String` divided by a comma or one (or more) white spaces.
\n * The latter is a deprecated method because it leads to confusion and will be\n * removed in v2.
\n * Additionally, it accepts additions and subtractions between different units.\n * Note that multiplications and divisions aren't supported.\n *\n * Valid examples are:\n * ```\n * 10\n * '10%'\n * '10, 10'\n * '10%, 10'\n * '10 + 10%'\n * '10 - 5vh + 3%'\n * '-10px + 5vh, 5px - 6%'\n * ```\n * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap\n * > with their reference element, unfortunately, you will have to disable the `flip` modifier.\n * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373)\n *\n * @memberof modifiers\n * @inner\n */\n offset: {\n /** @prop {number} order=200 - Index used to define the order of execution */\n order: 200,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: offset,\n /** @prop {Number|String} offset=0\n * The offset value as described in the modifier description\n */\n offset: 0\n },\n\n /**\n * Modifier used to prevent the popper from being positioned outside the boundary.\n *\n * An scenario exists where the reference itself is not within the boundaries.
\n * We can say it has \"escaped the boundaries\" — or just \"escaped\".
\n * In this case we need to decide whether the popper should either:\n *\n * - detach from the reference and remain \"trapped\" in the boundaries, or\n * - if it should ignore the boundary and \"escape with its reference\"\n *\n * When `escapeWithReference` is set to`true` and reference is completely\n * outside its boundaries, the popper will overflow (or completely leave)\n * the boundaries in order to remain attached to the edge of the reference.\n *\n * @memberof modifiers\n * @inner\n */\n preventOverflow: {\n /** @prop {number} order=300 - Index used to define the order of execution */\n order: 300,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: preventOverflow,\n /**\n * @prop {Array} [priority=['left','right','top','bottom']]\n * Popper will try to prevent overflow following these priorities by default,\n * then, it could overflow on the left and on top of the `boundariesElement`\n */\n priority: ['left', 'right', 'top', 'bottom'],\n /**\n * @prop {number} padding=5\n * Amount of pixel used to define a minimum distance between the boundaries\n * and the popper this makes sure the popper has always a little padding\n * between the edges of its container\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='scrollParent'\n * Boundaries used by the modifier, can be `scrollParent`, `window`,\n * `viewport` or any DOM element.\n */\n boundariesElement: 'scrollParent'\n },\n\n /**\n * Modifier used to make sure the reference and its popper stay near eachothers\n * without leaving any gap between the two. Expecially useful when the arrow is\n * enabled and you want to assure it to point to its reference element.\n * It cares only about the first axis, you can still have poppers with margin\n * between the popper and its reference element.\n * @memberof modifiers\n * @inner\n */\n keepTogether: {\n /** @prop {number} order=400 - Index used to define the order of execution */\n order: 400,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: keepTogether\n },\n\n /**\n * This modifier is used to move the `arrowElement` of the popper to make\n * sure it is positioned between the reference element and its popper element.\n * It will read the outer size of the `arrowElement` node to detect how many\n * pixels of conjuction are needed.\n *\n * It has no effect if no `arrowElement` is provided.\n * @memberof modifiers\n * @inner\n */\n arrow: {\n /** @prop {number} order=500 - Index used to define the order of execution */\n order: 500,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: arrow,\n /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */\n element: '[x-arrow]'\n },\n\n /**\n * Modifier used to flip the popper's placement when it starts to overlap its\n * reference element.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n *\n * **NOTE:** this modifier will interrupt the current update cycle and will\n * restart it if it detects the need to flip the placement.\n * @memberof modifiers\n * @inner\n */\n flip: {\n /** @prop {number} order=600 - Index used to define the order of execution */\n order: 600,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: flip,\n /**\n * @prop {String|Array} behavior='flip'\n * The behavior used to change the popper's placement. It can be one of\n * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid\n * placements (with optional variations).\n */\n behavior: 'flip',\n /**\n * @prop {number} padding=5\n * The popper will flip if it hits the edges of the `boundariesElement`\n */\n padding: 5,\n /**\n * @prop {String|HTMLElement} boundariesElement='viewport'\n * The element which will define the boundaries of the popper position,\n * the popper will never be placed outside of the defined boundaries\n * (except if keepTogether is enabled)\n */\n boundariesElement: 'viewport'\n },\n\n /**\n * Modifier used to make the popper flow toward the inner of the reference element.\n * By default, when this modifier is disabled, the popper will be placed outside\n * the reference element.\n * @memberof modifiers\n * @inner\n */\n inner: {\n /** @prop {number} order=700 - Index used to define the order of execution */\n order: 700,\n /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */\n enabled: false,\n /** @prop {ModifierFn} */\n fn: inner\n },\n\n /**\n * Modifier used to hide the popper when its reference element is outside of the\n * popper boundaries. It will set a `x-out-of-boundaries` attribute which can\n * be used to hide with a CSS selector the popper when its reference is\n * out of boundaries.\n *\n * Requires the `preventOverflow` modifier before it in order to work.\n * @memberof modifiers\n * @inner\n */\n hide: {\n /** @prop {number} order=800 - Index used to define the order of execution */\n order: 800,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: hide\n },\n\n /**\n * Computes the style that will be applied to the popper element to gets\n * properly positioned.\n *\n * Note that this modifier will not touch the DOM, it just prepares the styles\n * so that `applyStyle` modifier can apply it. This separation is useful\n * in case you need to replace `applyStyle` with a custom implementation.\n *\n * This modifier has `850` as `order` value to maintain backward compatibility\n * with previous versions of Popper.js. Expect the modifiers ordering method\n * to change in future major versions of the library.\n *\n * @memberof modifiers\n * @inner\n */\n computeStyle: {\n /** @prop {number} order=850 - Index used to define the order of execution */\n order: 850,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: computeStyle,\n /**\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3d transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties.\n */\n gpuAcceleration: true,\n /**\n * @prop {string} [x='bottom']\n * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.\n * Change this if your popper should grow in a direction different from `bottom`\n */\n x: 'bottom',\n /**\n * @prop {string} [x='left']\n * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.\n * Change this if your popper should grow in a direction different from `right`\n */\n y: 'right'\n },\n\n /**\n * Applies the computed styles to the popper element.\n *\n * All the DOM manipulations are limited to this modifier. This is useful in case\n * you want to integrate Popper.js inside a framework or view library and you\n * want to delegate all the DOM manipulations to it.\n *\n * Note that if you disable this modifier, you must make sure the popper element\n * has its position set to `absolute` before Popper.js can do its work!\n *\n * Just disable this modifier and define you own to achieve the desired effect.\n *\n * @memberof modifiers\n * @inner\n */\n applyStyle: {\n /** @prop {number} order=900 - Index used to define the order of execution */\n order: 900,\n /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */\n enabled: true,\n /** @prop {ModifierFn} */\n fn: applyStyle,\n /** @prop {Function} */\n onLoad: applyStyleOnLoad,\n /**\n * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier\n * @prop {Boolean} gpuAcceleration=true\n * If true, it uses the CSS 3d transformation to position the popper.\n * Otherwise, it will use the `top` and `left` properties.\n */\n gpuAcceleration: undefined\n }\n};\n\n/**\n * The `dataObject` is an object containing all the informations used by Popper.js\n * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.\n * @name dataObject\n * @property {Object} data.instance The Popper.js instance\n * @property {String} data.placement Placement applied to popper\n * @property {String} data.originalPlacement Placement originally defined on init\n * @property {Boolean} data.flipped True if popper has been flipped by flip modifier\n * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.\n * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier\n * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`)\n * @property {Object} data.boundaries Offsets of the popper boundaries\n * @property {Object} data.offsets The measurements of popper, reference and arrow elements.\n * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values\n * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0\n */\n\n/**\n * Default options provided to Popper.js constructor.
\n * These can be overriden using the `options` argument of Popper.js.
\n * To override an option, simply pass as 3rd argument an object with the same\n * structure of this object, example:\n * ```\n * new Popper(ref, pop, {\n * modifiers: {\n * preventOverflow: { enabled: false }\n * }\n * })\n * ```\n * @type {Object}\n * @static\n * @memberof Popper\n */\nvar Defaults = {\n /**\n * Popper's placement\n * @prop {Popper.placements} placement='bottom'\n */\n placement: 'bottom',\n\n /**\n * Set this to true if you want popper to position it self in 'fixed' mode\n * @prop {Boolean} positionFixed=false\n */\n positionFixed: false,\n\n /**\n * Whether events (resize, scroll) are initially enabled\n * @prop {Boolean} eventsEnabled=true\n */\n eventsEnabled: true,\n\n /**\n * Set to true if you want to automatically remove the popper when\n * you call the `destroy` method.\n * @prop {Boolean} removeOnDestroy=false\n */\n removeOnDestroy: false,\n\n /**\n * Callback called when the popper is created.
\n * By default, is set to no-op.
\n * Access Popper.js instance with `data.instance`.\n * @prop {onCreate}\n */\n onCreate: function onCreate() {},\n\n /**\n * Callback called when the popper is updated, this callback is not called\n * on the initialization/creation of the popper, but only on subsequent\n * updates.
\n * By default, is set to no-op.
\n * Access Popper.js instance with `data.instance`.\n * @prop {onUpdate}\n */\n onUpdate: function onUpdate() {},\n\n /**\n * List of modifiers used to modify the offsets before they are applied to the popper.\n * They provide most of the functionalities of Popper.js\n * @prop {modifiers}\n */\n modifiers: modifiers\n};\n\n/**\n * @callback onCreate\n * @param {dataObject} data\n */\n\n/**\n * @callback onUpdate\n * @param {dataObject} data\n */\n\n// Utils\n// Methods\nvar Popper = function () {\n /**\n * Create a new Popper.js instance\n * @class Popper\n * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper\n * @param {HTMLElement} popper - The HTML element used as popper.\n * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)\n * @return {Object} instance - The generated Popper.js instance\n */\n function Popper(reference, popper) {\n var _this = this;\n\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n classCallCheck(this, Popper);\n\n this.scheduleUpdate = function () {\n return requestAnimationFrame(_this.update);\n };\n\n // make update() debounced, so that it only runs at most once-per-tick\n this.update = debounce(this.update.bind(this));\n\n // with {} we create a new object with the options inside it\n this.options = _extends({}, Popper.Defaults, options);\n\n // init state\n this.state = {\n isDestroyed: false,\n isCreated: false,\n scrollParents: []\n };\n\n // get reference and popper elements (allow jQuery wrappers)\n this.reference = reference && reference.jquery ? reference[0] : reference;\n this.popper = popper && popper.jquery ? popper[0] : popper;\n\n // Deep merge modifiers options\n this.options.modifiers = {};\n Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {\n _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});\n });\n\n // Refactoring modifiers' list (Object => Array)\n this.modifiers = Object.keys(this.options.modifiers).map(function (name) {\n return _extends({\n name: name\n }, _this.options.modifiers[name]);\n })\n // sort the modifiers by order\n .sort(function (a, b) {\n return a.order - b.order;\n });\n\n // modifiers have the ability to execute arbitrary code when Popper.js get inited\n // such code is executed in the same order of its modifier\n // they could add new properties to their options configuration\n // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!\n this.modifiers.forEach(function (modifierOptions) {\n if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {\n modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);\n }\n });\n\n // fire the first update to position the popper in the right place\n this.update();\n\n var eventsEnabled = this.options.eventsEnabled;\n if (eventsEnabled) {\n // setup event listeners, they will take care of update the position in specific situations\n this.enableEventListeners();\n }\n\n this.state.eventsEnabled = eventsEnabled;\n }\n\n // We can't use class properties because they don't get listed in the\n // class prototype and break stuff like Sinon stubs\n\n\n createClass(Popper, [{\n key: 'update',\n value: function update$$1() {\n return update.call(this);\n }\n }, {\n key: 'destroy',\n value: function destroy$$1() {\n return destroy.call(this);\n }\n }, {\n key: 'enableEventListeners',\n value: function enableEventListeners$$1() {\n return enableEventListeners.call(this);\n }\n }, {\n key: 'disableEventListeners',\n value: function disableEventListeners$$1() {\n return disableEventListeners.call(this);\n }\n\n /**\n * Schedule an update, it will run on the next UI update available\n * @method scheduleUpdate\n * @memberof Popper\n */\n\n\n /**\n * Collection of utilities useful when writing custom modifiers.\n * Starting from version 1.7, this method is available only if you\n * include `popper-utils.js` before `popper.js`.\n *\n * **DEPRECATION**: This way to access PopperUtils is deprecated\n * and will be removed in v2! Use the PopperUtils module directly instead.\n * Due to the high instability of the methods contained in Utils, we can't\n * guarantee them to follow semver. Use them at your own risk!\n * @static\n * @private\n * @type {Object}\n * @deprecated since version 1.8\n * @member Utils\n * @memberof Popper\n */\n\n }]);\n return Popper;\n}();\n\n/**\n * The `referenceObject` is an object that provides an interface compatible with Popper.js\n * and lets you use it as replacement of a real DOM node.
\n * You can use this method to position a popper relatively to a set of coordinates\n * in case you don't have a DOM node to use as reference.\n *\n * ```\n * new Popper(referenceObject, popperNode);\n * ```\n *\n * NB: This feature isn't supported in Internet Explorer 10\n * @name referenceObject\n * @property {Function} data.getBoundingClientRect\n * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.\n * @property {number} data.clientWidth\n * An ES6 getter that will return the width of the virtual reference element.\n * @property {number} data.clientHeight\n * An ES6 getter that will return the height of the virtual reference element.\n */\n\n\nPopper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;\nPopper.placements = placements;\nPopper.Defaults = Defaults;\n\nexport default Popper;\n//# sourceMappingURL=popper.js.map\n","import $ from 'jquery'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): util.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Util = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\n const TRANSITION_END = 'transitionend'\n const MAX_UID = 1000000\n const MILLISECONDS_MULTIPLIER = 1000\n\n // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n function toType(obj) {\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n }\n\n function getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n return undefined // eslint-disable-line no-undefined\n }\n }\n }\n\n function transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n }\n\n function setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n }\n\n /**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\n const Util = {\n\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n // eslint-disable-next-line no-bitwise\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n if (!selector || selector === '#') {\n selector = element.getAttribute('href') || ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (err) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n const floatTransitionDuration = parseFloat(transitionDuration)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n\n return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n // TODO: Remove in v5\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value)\n ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n }\n }\n\n setTransitionEndSupport()\n\n return Util\n})($)\n\nexport default Util\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Alert = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'alert'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.alert'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Selector = {\n DISMISS : '[data-dismiss=\"alert\"]'\n }\n\n const Event = {\n CLOSE : `close${EVENT_KEY}`,\n CLOSED : `closed${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n ALERT : 'alert',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${ClassName.ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(Event.CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(ClassName.SHOW)\n\n if (!$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(Event.CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(\n Event.CLICK_DATA_API,\n Selector.DISMISS,\n Alert._handleDismiss(new Alert())\n )\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Alert._jQueryInterface\n $.fn[NAME].Constructor = Alert\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n }\n\n return Alert\n})($)\n\nexport default Alert\n","import $ from 'jquery'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Button = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'button'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.button'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const ClassName = {\n ACTIVE : 'active',\n BUTTON : 'btn',\n FOCUS : 'focus'\n }\n\n const Selector = {\n DATA_TOGGLE_CARROT : '[data-toggle^=\"button\"]',\n DATA_TOGGLE : '[data-toggle=\"buttons\"]',\n INPUT : 'input',\n ACTIVE : '.active',\n BUTTON : '.btn'\n }\n\n const Event = {\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Button {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(\n Selector.DATA_TOGGLE\n )[0]\n\n if (rootElement) {\n const input = this._element.querySelector(Selector.INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked &&\n this._element.classList.contains(ClassName.ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(Selector.ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(ClassName.ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n if (input.hasAttribute('disabled') ||\n rootElement.hasAttribute('disabled') ||\n input.classList.contains('disabled') ||\n rootElement.classList.contains('disabled')) {\n return\n }\n input.checked = !this._element.classList.contains(ClassName.ACTIVE)\n $(input).trigger('change')\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed',\n !this._element.classList.contains(ClassName.ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(ClassName.ACTIVE)\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $(this).data(DATA_KEY, data)\n }\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n event.preventDefault()\n\n let button = event.target\n\n if (!$(button).hasClass(ClassName.BUTTON)) {\n button = $(button).closest(Selector.BUTTON)\n }\n\n Button._jQueryInterface.call($(button), 'toggle')\n })\n .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n const button = $(event.target).closest(Selector.BUTTON)[0]\n $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Button._jQueryInterface\n $.fn[NAME].Constructor = Button\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n }\n\n return Button\n})($)\n\nexport default Button\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Carousel = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'carousel'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.carousel'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\n const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\n const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\n const Default = {\n interval : 5000,\n keyboard : true,\n slide : false,\n pause : 'hover',\n wrap : true\n }\n\n const DefaultType = {\n interval : '(number|boolean)',\n keyboard : 'boolean',\n slide : '(boolean|string)',\n pause : '(string|boolean)',\n wrap : 'boolean'\n }\n\n const Direction = {\n NEXT : 'next',\n PREV : 'prev',\n LEFT : 'left',\n RIGHT : 'right'\n }\n\n const Event = {\n SLIDE : `slide${EVENT_KEY}`,\n SLID : `slid${EVENT_KEY}`,\n KEYDOWN : `keydown${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`,\n TOUCHEND : `touchend${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n CAROUSEL : 'carousel',\n ACTIVE : 'active',\n SLIDE : 'slide',\n RIGHT : 'carousel-item-right',\n LEFT : 'carousel-item-left',\n NEXT : 'carousel-item-next',\n PREV : 'carousel-item-prev',\n ITEM : 'carousel-item'\n }\n\n const Selector = {\n ACTIVE : '.active',\n ACTIVE_ITEM : '.active.carousel-item',\n ITEM : '.carousel-item',\n NEXT_PREV : '.carousel-item-next, .carousel-item-prev',\n INDICATORS : '.carousel-indicators',\n DATA_SLIDE : '[data-slide], [data-slide-to]',\n DATA_RIDE : '[data-ride=\"carousel\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n\n this._isPaused = false\n this._isSliding = false\n\n this.touchTimeout = null\n\n this._config = this._getConfig(config)\n this._element = $(element)[0]\n this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT)\n }\n }\n\n nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(Selector.NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(Event.SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex\n ? Direction.NEXT\n : Direction.PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element)\n .on(Event.KEYDOWN, (event) => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(Event.MOUSEENTER, (event) => this.pause(event))\n .on(Event.MOUSELEAVE, (event) => this.cycle(event))\n if ('ontouchstart' in document.documentElement) {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n $(this._element).on(Event.TOUCHEND, () => {\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n })\n }\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode\n ? [].slice.call(element.parentNode.querySelectorAll(Selector.ITEM))\n : []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === Direction.NEXT\n const isPrevDirection = direction === Direction.PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === Direction.PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1\n ? this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(Selector.ACTIVE_ITEM))\n const slideEvent = $.Event(Event.SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector.ACTIVE))\n $(indicators)\n .removeClass(ClassName.ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName.ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName.LEFT\n orderClassName = ClassName.NEXT\n eventDirectionName = Direction.LEFT\n } else {\n directionalClassName = ClassName.RIGHT\n orderClassName = ClassName.PREV\n eventDirectionName = Direction.RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(Event.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(ClassName.SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(ClassName.ACTIVE)\n\n $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(ClassName.ACTIVE)\n $(nextElement).addClass(ClassName.ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n data[action]()\n } else if (_config.interval) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)\n\n $(window).on(Event.LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(Selector.DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Carousel._jQueryInterface\n $.fn[NAME].Constructor = Carousel\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n }\n\n return Carousel\n})($)\n\nexport default Carousel\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Collapse = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'collapse'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.collapse'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Default = {\n toggle : true,\n parent : ''\n }\n\n const DefaultType = {\n toggle : 'boolean',\n parent : '(string|element)'\n }\n\n const Event = {\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SHOW : 'show',\n COLLAPSE : 'collapse',\n COLLAPSING : 'collapsing',\n COLLAPSED : 'collapsed'\n }\n\n const Dimension = {\n WIDTH : 'width',\n HEIGHT : 'height'\n }\n\n const Selector = {\n ACTIVES : '.show, .collapsing',\n DATA_TOGGLE : '[data-toggle=\"collapse\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = $.makeArray(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter((foundElem) => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(ClassName.SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))\n .filter((elem) => elem.getAttribute('data-parent') === this._config.parent)\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(Event.SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(ClassName.COLLAPSE)\n .addClass(ClassName.COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(ClassName.COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .addClass(ClassName.SHOW)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(Event.SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n const startEvent = $.Event(Event.HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(ClassName.COLLAPSING)\n .removeClass(ClassName.COLLAPSE)\n .removeClass(ClassName.SHOW)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(ClassName.SHOW)) {\n $(trigger).addClass(ClassName.COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .trigger(Event.HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(Dimension.WIDTH)\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT\n }\n\n _getParent() {\n let parent = null\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector =\n `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n\n const children = [].slice.call(parent.querySelectorAll(selector))\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n if (element) {\n const isOpen = $(element).hasClass(ClassName.SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(ClassName.COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$this.data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n // preventDefault only for
elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Collapse._jQueryInterface\n $.fn[NAME].Constructor = Collapse\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n }\n\n return Collapse\n})($)\n\nexport default Collapse\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Dropdown = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'dropdown'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.dropdown'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\n const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\n const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\n const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\n const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\n const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,\n KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DISABLED : 'disabled',\n SHOW : 'show',\n DROPUP : 'dropup',\n DROPRIGHT : 'dropright',\n DROPLEFT : 'dropleft',\n MENURIGHT : 'dropdown-menu-right',\n MENULEFT : 'dropdown-menu-left',\n POSITION_STATIC : 'position-static'\n }\n\n const Selector = {\n DATA_TOGGLE : '[data-toggle=\"dropdown\"]',\n FORM_CHILD : '.dropdown form',\n MENU : '.dropdown-menu',\n NAVBAR_NAV : '.navbar-nav',\n VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n }\n\n const AttachmentMap = {\n TOP : 'top-start',\n TOPEND : 'top-end',\n BOTTOM : 'bottom-start',\n BOTTOMEND : 'bottom-end',\n RIGHT : 'right-start',\n RIGHTEND : 'right-end',\n LEFT : 'left-start',\n LEFTEND : 'left-end'\n }\n\n const Default = {\n offset : 0,\n flip : true,\n boundary : 'scrollParent',\n reference : 'toggle',\n display : 'dynamic'\n }\n\n const DefaultType = {\n offset : '(number|string|function)',\n flip : 'boolean',\n boundary : '(string|element)',\n reference : '(string|element)',\n display : 'string'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this._element)\n const isActive = $(this._menu).hasClass(ClassName.SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(Event.SHOW, relatedTarget)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(ClassName.POSITION_STATIC)\n }\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(Selector.NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.SHOWN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(Event.CLICK, (event) => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n if (parent) {\n this._menu = parent.querySelector(Selector.MENU)\n }\n }\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = AttachmentMap.BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(ClassName.DROPUP)) {\n placement = AttachmentMap.TOP\n if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.TOPEND\n }\n } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {\n placement = AttachmentMap.RIGHT\n } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {\n placement = AttachmentMap.LEFT\n } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.BOTTOMEND\n }\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getPopperConfig() {\n const offsetConf = {}\n if (typeof this._config.offset === 'function') {\n offsetConf.fn = (data) => {\n data.offsets = {\n ...data.offsets,\n ...this._config.offset(data.offsets) || {}\n }\n return data\n }\n } else {\n offsetConf.offset = this._config.offset\n }\n\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: offsetConf,\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n return popperConfig\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(ClassName.SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(Event.HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n $(dropdownMenu).removeClass(ClassName.SHOW)\n $(parent)\n .removeClass(ClassName.SHOW)\n .trigger($.Event(Event.HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName)\n ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(ClassName.SHOW)\n\n if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) ||\n isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n const toggle = parent.querySelector(Selector.DATA_TOGGLE)\n $(toggle).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)\n .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {\n e.stopPropagation()\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Dropdown._jQueryInterface\n $.fn[NAME].Constructor = Dropdown\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n }\n\n return Dropdown\n})($, Popper)\n\nexport default Dropdown\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Modal = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'modal'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.modal'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\n const Default = {\n backdrop : true,\n keyboard : true,\n focus : true,\n show : true\n }\n\n const DefaultType = {\n backdrop : '(boolean|string)',\n keyboard : 'boolean',\n focus : 'boolean',\n show : 'boolean'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n RESIZE : `resize${EVENT_KEY}`,\n CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,\n KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,\n MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,\n MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SCROLLBAR_MEASURER : 'modal-scrollbar-measure',\n BACKDROP : 'modal-backdrop',\n OPEN : 'modal-open',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n DIALOG : '.modal-dialog',\n DATA_TOGGLE : '[data-toggle=\"modal\"]',\n DATA_DISMISS : '[data-dismiss=\"modal\"]',\n FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT : '.sticky-top'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(Selector.DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isTransitioning || this._isShown) {\n return\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n $(document.body).addClass(ClassName.OPEN)\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n Event.CLICK_DISMISS,\n Selector.DATA_DISMISS,\n (event) => this.hide(event)\n )\n\n $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {\n $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (this._isTransitioning || !this._isShown) {\n return\n }\n\n const hideEvent = $.Event(Event.HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(Event.FOCUSIN)\n\n $(this._element).removeClass(ClassName.SHOW)\n\n $(this._element).off(Event.CLICK_DISMISS)\n $(this._dialog).off(Event.MOUSEDOWN_DISMISS)\n\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, (event) => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n $(window, document, this._element, this._backdrop).off(EVENT_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.scrollTop = 0\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(ClassName.SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(Event.FOCUSIN) // Guard against infinite focus loop\n .on(Event.FOCUSIN, (event) => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {\n if (event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(Event.KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))\n } else {\n $(window).off(Event.RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(ClassName.OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(Event.HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(ClassName.FADE)\n ? ClassName.FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = ClassName.BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(Event.CLICK_DISMISS, (event) => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n if (event.target !== event.currentTarget) {\n return\n }\n if (this._config.backdrop === 'static') {\n this._element.focus()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(ClassName.SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName.SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing =\n this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = ClassName.SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY)\n ? 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(Event.SHOW, (showEvent) => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(Event.HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Modal._jQueryInterface\n $.fn[NAME].Constructor = Modal\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n }\n\n return Modal\n})($)\n\nexport default Modal\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Tooltip = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'tooltip'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.tooltip'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const CLASS_PREFIX = 'bs-tooltip'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const DefaultType = {\n animation : 'boolean',\n template : 'string',\n title : '(string|element|function)',\n trigger : 'string',\n delay : '(number|object)',\n html : 'boolean',\n selector : '(string|boolean)',\n placement : '(string|function)',\n offset : '(number|string)',\n container : '(string|element|boolean)',\n fallbackPlacement : '(string|array)',\n boundary : '(string|element)'\n }\n\n const AttachmentMap = {\n AUTO : 'auto',\n TOP : 'top',\n RIGHT : 'right',\n BOTTOM : 'bottom',\n LEFT : 'left'\n }\n\n const Default = {\n animation : true,\n template : '
' +\n '
' +\n '
',\n trigger : 'hover focus',\n title : '',\n delay : 0,\n html : false,\n selector : false,\n placement : 'top',\n offset : 0,\n container : false,\n fallbackPlacement : 'flip',\n boundary : 'scrollParent'\n }\n\n const HoverState = {\n SHOW : 'show',\n OUT : 'out'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TOOLTIP : '.tooltip',\n TOOLTIP_INNER : '.tooltip-inner',\n ARROW : '.arrow'\n }\n\n const Trigger = {\n HOVER : 'hover',\n FOCUS : 'focus',\n CLICK : 'click',\n MANUAL : 'manual'\n }\n\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Tooltip {\n constructor(element, config) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal')\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const isInTheDom = $.contains(\n this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(ClassName.FADE)\n }\n\n const placement = typeof this.config.placement === 'function'\n ? this.config.placement.call(this, tip, this.element)\n : this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this.config.container === false ? document.body : $(document).find(this.config.container)\n\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, {\n placement: attachment,\n modifiers: {\n offset: {\n offset: this.config.offset\n },\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: Selector.ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: (data) => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: (data) => {\n this._handlePopperPlacementChange(data)\n }\n })\n\n $(tip).addClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HoverState.OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HoverState.SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[Trigger.CLICK] = false\n this._activeTrigger[Trigger.FOCUS] = false\n this._activeTrigger[Trigger.HOVER] = false\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n setElementContent($element, content) {\n const html = this.config.html\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n } else {\n $element[html ? 'html' : 'text'](content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function'\n ? this.config.title.call(this.element)\n : this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach((trigger) => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n (event) => this.toggle(event)\n )\n } else if (trigger !== Trigger.MANUAL) {\n const eventIn = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSEENTER\n : this.constructor.Event.FOCUSIN\n const eventOut = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSELEAVE\n : this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(\n eventIn,\n this.config.selector,\n (event) => this._enter(event)\n )\n .on(\n eventOut,\n this.config.selector,\n (event) => this._leave(event)\n )\n }\n\n $(this.element).closest('.modal').on(\n 'hide.bs.modal',\n () => this.hide()\n )\n })\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n if (this.element.getAttribute('title') ||\n titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||\n context._hoverState === HoverState.SHOW) {\n context._hoverState = HoverState.SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this.element).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n const popperInstance = popperData.instance\n this.tip = popperInstance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n $(tip).removeClass(ClassName.FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Tooltip._jQueryInterface\n $.fn[NAME].Constructor = Tooltip\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n }\n\n return Tooltip\n})($, Popper)\n\nexport default Tooltip\n","import $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Popover = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'popover'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.popover'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const CLASS_PREFIX = 'bs-popover'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const Default = {\n ...Tooltip.Default,\n placement : 'right',\n trigger : 'click',\n content : '',\n template : '
' +\n '
' +\n '

' +\n '
'\n }\n\n const DefaultType = {\n ...Tooltip.DefaultType,\n content : '(string|element|function)'\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TITLE : '.popover-header',\n CONTENT : '.popover-body'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(Selector.TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n this.setElementContent($tip.find(Selector.CONTENT), content)\n\n $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /destroy|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Popover._jQueryInterface\n $.fn[NAME].Constructor = Popover\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n }\n\n return Popover\n})($)\n\nexport default Popover\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst ScrollSpy = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'scrollspy'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.scrollspy'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Default = {\n offset : 10,\n method : 'auto',\n target : ''\n }\n\n const DefaultType = {\n offset : 'number',\n method : 'string',\n target : '(string|element)'\n }\n\n const Event = {\n ACTIVATE : `activate${EVENT_KEY}`,\n SCROLL : `scroll${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DROPDOWN_ITEM : 'dropdown-item',\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active'\n }\n\n const Selector = {\n DATA_SPY : '[data-spy=\"scroll\"]',\n ACTIVE : '.active',\n NAV_LIST_GROUP : '.nav, .list-group',\n NAV_LINKS : '.nav-link',\n NAV_ITEMS : '.nav-item',\n LIST_ITEMS : '.list-group-item',\n DROPDOWN : '.dropdown',\n DROPDOWN_ITEMS : '.dropdown-item',\n DROPDOWN_TOGGLE : '.dropdown-toggle'\n }\n\n const OffsetMethod = {\n OFFSET : 'offset',\n POSITION : 'position'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +\n `${this._config.target} ${Selector.LIST_ITEMS},` +\n `${this._config.target} ${Selector.DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window\n ? OffsetMethod.OFFSET : OffsetMethod.POSITION\n\n const offsetMethod = this._config.method === 'auto'\n ? autoMethod : this._config.method\n\n const offsetBase = offsetMethod === OffsetMethod.POSITION\n ? this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map((element) => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n return null\n })\n .filter((item) => item)\n .sort((a, b) => a[0] - b[0])\n .forEach((item) => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.target !== 'string') {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window\n ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window\n ? window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset +\n scrollHeight -\n this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n const offsetLength = this._offsets.length\n for (let i = offsetLength; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n let queries = this._selector.split(',')\n // eslint-disable-next-line arrow-body-style\n queries = queries.map((selector) => {\n return `${selector}[data-target=\"${target}\"],` +\n `${selector}[href=\"${target}\"]`\n })\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {\n $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n $link.addClass(ClassName.ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(ClassName.ACTIVE)\n // Set triggered links parents as active\n // With both
',trigger:"hover focus",title:"",delay:0,html:!(Ie={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(Se={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},we="out",Ne={HIDE:"hide"+Ee,HIDDEN:"hidden"+Ee,SHOW:(De="show")+Ee,SHOWN:"shown"+Ee,INSERTED:"inserted"+Ee,CLICK:"click"+Ee,FOCUSIN:"focusin"+Ee,FOCUSOUT:"focusout"+Ee,MOUSEENTER:"mouseenter"+Ee,MOUSELEAVE:"mouseleave"+Ee},Oe="fade",ke="show",Pe=".tooltip-inner",je=".arrow",He="hover",Le="focus",Re="click",xe="manual",We=function(){function i(t,e){if("undefined"==typeof h)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=pe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(pe(this.getTipElement()).hasClass(ke))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),pe.removeData(this.element,this.constructor.DATA_KEY),pe(this.element).off(this.constructor.EVENT_KEY),pe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&pe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===pe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=pe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){pe(this.element).trigger(t);var n=pe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Fn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&pe(i).addClass(Oe);var o="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var a=!1===this.config.container?document.body:pe(document).find(this.config.container);pe(i).data(this.constructor.DATA_KEY,this),pe.contains(this.element.ownerDocument.documentElement,this.tip)||pe(i).appendTo(a),pe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new h(this.element,i,{placement:s,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:je},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),pe(i).addClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().on("mouseover",null,pe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,pe(e.element).trigger(e.constructor.Event.SHOWN),t===we&&e._leave(null,e)};if(pe(this.tip).hasClass(Oe)){var c=Fn.getTransitionDurationFromElement(this.tip);pe(this.tip).one(Fn.TRANSITION_END,l).emulateTransitionEnd(c)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=pe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==De&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),pe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(pe(this.element).trigger(i),!i.isDefaultPrevented()){if(pe(n).removeClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().off("mouseover",null,pe.noop),this._activeTrigger[Re]=!1,this._activeTrigger[Le]=!1,this._activeTrigger[He]=!1,pe(this.tip).hasClass(Oe)){var o=Fn.getTransitionDurationFromElement(n);pe(n).one(Fn.TRANSITION_END,r).emulateTransitionEnd(o)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){pe(this.getTipElement()).addClass(Te+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||pe(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(pe(t.querySelectorAll(Pe)),this.getTitle()),pe(t).removeClass(Oe+" "+ke)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?pe(e).parent().is(t)||t.empty().append(e):t.text(pe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return Ie[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)pe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==xe){var e=t===He?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===He?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;pe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}pe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Le:He]=!0),pe(e.getTipElement()).hasClass(ke)||e._hoverState===De?e._hoverState=De:(clearTimeout(e._timeout),e._hoverState=De,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===De&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Le:He]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=we,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===we&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=l({},this.constructor.Default,pe(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Fn.typeCheckConfig(ve,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=pe(this.getTipElement()),e=t.attr("class").match(be);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(pe(t).removeClass(Oe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=pe(this).data(ye),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),pe(this).data(ye,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.1.3"}},{key:"Default",get:function(){return Ae}},{key:"NAME",get:function(){return ve}},{key:"DATA_KEY",get:function(){return ye}},{key:"Event",get:function(){return Ne}},{key:"EVENT_KEY",get:function(){return Ee}},{key:"DefaultType",get:function(){return Se}}]),i}(),pe.fn[ve]=We._jQueryInterface,pe.fn[ve].Constructor=We,pe.fn[ve].noConflict=function(){return pe.fn[ve]=Ce,We._jQueryInterface},We),Jn=(qe="popover",Ke="."+(Fe="bs.popover"),Me=(Ue=e).fn[qe],Qe="bs-popover",Be=new RegExp("(^|\\s)"+Qe+"\\S+","g"),Ve=l({},zn.Default,{placement:"right",trigger:"click",content:"",template:''}),Ye=l({},zn.DefaultType,{content:"(string|element|function)"}),ze="fade",Ze=".popover-header",Ge=".popover-body",$e={HIDE:"hide"+Ke,HIDDEN:"hidden"+Ke,SHOW:(Je="show")+Ke,SHOWN:"shown"+Ke,INSERTED:"inserted"+Ke,CLICK:"click"+Ke,FOCUSIN:"focusin"+Ke,FOCUSOUT:"focusout"+Ke,MOUSEENTER:"mouseenter"+Ke,MOUSELEAVE:"mouseleave"+Ke},Xe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){Ue(this.getTipElement()).addClass(Qe+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||Ue(this.config.template)[0],this.tip},r.setContent=function(){var t=Ue(this.getTipElement());this.setElementContent(t.find(Ze),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ge),e),t.removeClass(ze+" "+Je)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=Ue(this.getTipElement()),e=t.attr("class").match(Be);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||tthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Ee},je="show",He="out",Re={HIDE:"hide"+De,HIDDEN:"hidden"+De,SHOW:"show"+De,SHOWN:"shown"+De,INSERTED:"inserted"+De,CLICK:"click"+De,FOCUSIN:"focusin"+De,FOCUSOUT:"focusout"+De,MOUSEENTER:"mouseenter"+De,MOUSELEAVE:"mouseleave"+De},xe="fade",Fe="show",Ue=".tooltip-inner",We=".arrow",qe="hover",Me="focus",Ke="click",Qe="manual",Be=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Fe))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(xe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:We},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),g(o).addClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===He&&e._leave(null,e)};if(g(this.tip).hasClass(xe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=g.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==je&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),g(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(g(this.element).trigger(i),!i.isDefaultPrevented()){if(g(n).removeClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ke]=!1,this._activeTrigger[Me]=!1,this._activeTrigger[qe]=!1,g(this.tip).hasClass(xe)){var r=_.getTransitionDurationFromElement(n);g(n).one(_.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Ae+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ue)),this.getTitle()),g(t).removeClass(xe+" "+Fe)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Se(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Pe[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Qe){var e=t===qe?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===qe?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),g(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Me:qe]=!0),g(e.getTipElement()).hasClass(Fe)||e._hoverState===je?e._hoverState=je:(clearTimeout(e._timeout),e._hoverState=je,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===je&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Me:qe]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=He,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===He&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==Oe.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(be,t,this.constructor.DefaultType),t.sanitize&&(t.template=Se(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ne);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(xe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ie),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ie,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Le}},{key:"NAME",get:function(){return be}},{key:"DATA_KEY",get:function(){return Ie}},{key:"Event",get:function(){return Re}},{key:"EVENT_KEY",get:function(){return De}},{key:"DefaultType",get:function(){return ke}}]),i}();g.fn[be]=Be._jQueryInterface,g.fn[be].Constructor=Be,g.fn[be].noConflict=function(){return g.fn[be]=we,Be._jQueryInterface};var Ve="popover",Ye="bs.popover",ze="."+Ye,Xe=g.fn[Ve],$e="bs-popover",Ge=new RegExp("(^|\\s)"+$e+"\\S+","g"),Je=l({},Be.Default,{placement:"right",trigger:"click",content:"",template:''}),Ze=l({},Be.DefaultType,{content:"(string|element|function)"}),tn="fade",en="show",nn=".popover-header",on=".popover-body",rn={HIDE:"hide"+ze,HIDDEN:"hidden"+ze,SHOW:"show"+ze,SHOWN:"shown"+ze,INSERTED:"inserted"+ze,CLICK:"click"+ze,FOCUSIN:"focusin"+ze,FOCUSOUT:"focusout"+ze,MOUSEENTER:"mouseenter"+ze,MOUSELEAVE:"mouseleave"+ze},sn=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){g(this.getTipElement()).addClass($e+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},o.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(nn),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(on),e),t.removeClass(tn+" "+en)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ge);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t {\n /**\n * ------------------------------------------------------------------------\n * Private TransitionEnd Helpers\n * ------------------------------------------------------------------------\n */\n\n const TRANSITION_END = 'transitionend'\n const MAX_UID = 1000000\n const MILLISECONDS_MULTIPLIER = 1000\n\n // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n function toType(obj) {\n return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase()\n }\n\n function getSpecialTransitionEndEvent() {\n return {\n bindType: TRANSITION_END,\n delegateType: TRANSITION_END,\n handle(event) {\n if ($(event.target).is(this)) {\n return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params\n }\n return undefined // eslint-disable-line no-undefined\n }\n }\n }\n\n function transitionEndEmulator(duration) {\n let called = false\n\n $(this).one(Util.TRANSITION_END, () => {\n called = true\n })\n\n setTimeout(() => {\n if (!called) {\n Util.triggerTransitionEnd(this)\n }\n }, duration)\n\n return this\n }\n\n function setTransitionEndSupport() {\n $.fn.emulateTransitionEnd = transitionEndEmulator\n $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()\n }\n\n /**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\n const Util = {\n\n TRANSITION_END: 'bsTransitionEnd',\n\n getUID(prefix) {\n do {\n // eslint-disable-next-line no-bitwise\n prefix += ~~(Math.random() * MAX_UID) // \"~~\" acts like a faster Math.floor() here\n } while (document.getElementById(prefix))\n return prefix\n },\n\n getSelectorFromElement(element) {\n let selector = element.getAttribute('data-target')\n if (!selector || selector === '#') {\n selector = element.getAttribute('href') || ''\n }\n\n try {\n return document.querySelector(selector) ? selector : null\n } catch (err) {\n return null\n }\n },\n\n getTransitionDurationFromElement(element) {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let transitionDuration = $(element).css('transition-duration')\n const floatTransitionDuration = parseFloat(transitionDuration)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n\n return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER\n },\n\n reflow(element) {\n return element.offsetHeight\n },\n\n triggerTransitionEnd(element) {\n $(element).trigger(TRANSITION_END)\n },\n\n // TODO: Remove in v5\n supportsTransitionEnd() {\n return Boolean(TRANSITION_END)\n },\n\n isElement(obj) {\n return (obj[0] || obj).nodeType\n },\n\n typeCheckConfig(componentName, config, configTypes) {\n for (const property in configTypes) {\n if (Object.prototype.hasOwnProperty.call(configTypes, property)) {\n const expectedTypes = configTypes[property]\n const value = config[property]\n const valueType = value && Util.isElement(value)\n ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new Error(\n `${componentName.toUpperCase()}: ` +\n `Option \"${property}\" provided type \"${valueType}\" ` +\n `but expected type \"${expectedTypes}\".`)\n }\n }\n }\n }\n }\n\n setTransitionEndSupport()\n\n return Util\n})($)\n\nexport default Util\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Alert = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'alert'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.alert'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Selector = {\n DISMISS : '[data-dismiss=\"alert\"]'\n }\n\n const Event = {\n CLOSE : `close${EVENT_KEY}`,\n CLOSED : `closed${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n ALERT : 'alert',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Alert {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n close(element) {\n let rootElement = this._element\n if (element) {\n rootElement = this._getRootElement(element)\n }\n\n const customEvent = this._triggerCloseEvent(rootElement)\n\n if (customEvent.isDefaultPrevented()) {\n return\n }\n\n this._removeElement(rootElement)\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Private\n\n _getRootElement(element) {\n const selector = Util.getSelectorFromElement(element)\n let parent = false\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n if (!parent) {\n parent = $(element).closest(`.${ClassName.ALERT}`)[0]\n }\n\n return parent\n }\n\n _triggerCloseEvent(element) {\n const closeEvent = $.Event(Event.CLOSE)\n\n $(element).trigger(closeEvent)\n return closeEvent\n }\n\n _removeElement(element) {\n $(element).removeClass(ClassName.SHOW)\n\n if (!$(element).hasClass(ClassName.FADE)) {\n this._destroyElement(element)\n return\n }\n\n const transitionDuration = Util.getTransitionDurationFromElement(element)\n\n $(element)\n .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event))\n .emulateTransitionEnd(transitionDuration)\n }\n\n _destroyElement(element) {\n $(element)\n .detach()\n .trigger(Event.CLOSED)\n .remove()\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $element = $(this)\n let data = $element.data(DATA_KEY)\n\n if (!data) {\n data = new Alert(this)\n $element.data(DATA_KEY, data)\n }\n\n if (config === 'close') {\n data[config](this)\n }\n })\n }\n\n static _handleDismiss(alertInstance) {\n return function (event) {\n if (event) {\n event.preventDefault()\n }\n\n alertInstance.close(this)\n }\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(\n Event.CLICK_DATA_API,\n Selector.DISMISS,\n Alert._handleDismiss(new Alert())\n )\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Alert._jQueryInterface\n $.fn[NAME].Constructor = Alert\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Alert._jQueryInterface\n }\n\n return Alert\n})($)\n\nexport default Alert\n","import $ from 'jquery'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Button = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'button'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.button'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const ClassName = {\n ACTIVE : 'active',\n BUTTON : 'btn',\n FOCUS : 'focus'\n }\n\n const Selector = {\n DATA_TOGGLE_CARROT : '[data-toggle^=\"button\"]',\n DATA_TOGGLE : '[data-toggle=\"buttons\"]',\n INPUT : 'input',\n ACTIVE : '.active',\n BUTTON : '.btn'\n }\n\n const Event = {\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} ` +\n `blur${EVENT_KEY}${DATA_API_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Button {\n constructor(element) {\n this._element = element\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n // Public\n\n toggle() {\n let triggerChangeEvent = true\n let addAriaPressed = true\n const rootElement = $(this._element).closest(\n Selector.DATA_TOGGLE\n )[0]\n\n if (rootElement) {\n const input = this._element.querySelector(Selector.INPUT)\n\n if (input) {\n if (input.type === 'radio') {\n if (input.checked &&\n this._element.classList.contains(ClassName.ACTIVE)) {\n triggerChangeEvent = false\n } else {\n const activeElement = rootElement.querySelector(Selector.ACTIVE)\n\n if (activeElement) {\n $(activeElement).removeClass(ClassName.ACTIVE)\n }\n }\n }\n\n if (triggerChangeEvent) {\n if (input.hasAttribute('disabled') ||\n rootElement.hasAttribute('disabled') ||\n input.classList.contains('disabled') ||\n rootElement.classList.contains('disabled')) {\n return\n }\n input.checked = !this._element.classList.contains(ClassName.ACTIVE)\n $(input).trigger('change')\n }\n\n input.focus()\n addAriaPressed = false\n }\n }\n\n if (addAriaPressed) {\n this._element.setAttribute('aria-pressed',\n !this._element.classList.contains(ClassName.ACTIVE))\n }\n\n if (triggerChangeEvent) {\n $(this._element).toggleClass(ClassName.ACTIVE)\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n this._element = null\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n\n if (!data) {\n data = new Button(this)\n $(this).data(DATA_KEY, data)\n }\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n event.preventDefault()\n\n let button = event.target\n\n if (!$(button).hasClass(ClassName.BUTTON)) {\n button = $(button).closest(Selector.BUTTON)\n }\n\n Button._jQueryInterface.call($(button), 'toggle')\n })\n .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {\n const button = $(event.target).closest(Selector.BUTTON)[0]\n $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Button._jQueryInterface\n $.fn[NAME].Constructor = Button\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Button._jQueryInterface\n }\n\n return Button\n})($)\n\nexport default Button\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Carousel = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'carousel'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.carousel'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key\n const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key\n const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\n const Default = {\n interval : 5000,\n keyboard : true,\n slide : false,\n pause : 'hover',\n wrap : true\n }\n\n const DefaultType = {\n interval : '(number|boolean)',\n keyboard : 'boolean',\n slide : '(boolean|string)',\n pause : '(string|boolean)',\n wrap : 'boolean'\n }\n\n const Direction = {\n NEXT : 'next',\n PREV : 'prev',\n LEFT : 'left',\n RIGHT : 'right'\n }\n\n const Event = {\n SLIDE : `slide${EVENT_KEY}`,\n SLID : `slid${EVENT_KEY}`,\n KEYDOWN : `keydown${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`,\n TOUCHEND : `touchend${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n CAROUSEL : 'carousel',\n ACTIVE : 'active',\n SLIDE : 'slide',\n RIGHT : 'carousel-item-right',\n LEFT : 'carousel-item-left',\n NEXT : 'carousel-item-next',\n PREV : 'carousel-item-prev',\n ITEM : 'carousel-item'\n }\n\n const Selector = {\n ACTIVE : '.active',\n ACTIVE_ITEM : '.active.carousel-item',\n ITEM : '.carousel-item',\n NEXT_PREV : '.carousel-item-next, .carousel-item-prev',\n INDICATORS : '.carousel-indicators',\n DATA_SLIDE : '[data-slide], [data-slide-to]',\n DATA_RIDE : '[data-ride=\"carousel\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Carousel {\n constructor(element, config) {\n this._items = null\n this._interval = null\n this._activeElement = null\n\n this._isPaused = false\n this._isSliding = false\n\n this.touchTimeout = null\n\n this._config = this._getConfig(config)\n this._element = $(element)[0]\n this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n next() {\n if (!this._isSliding) {\n this._slide(Direction.NEXT)\n }\n }\n\n nextWhenVisible() {\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden &&\n ($(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden')) {\n this.next()\n }\n }\n\n prev() {\n if (!this._isSliding) {\n this._slide(Direction.PREV)\n }\n }\n\n pause(event) {\n if (!event) {\n this._isPaused = true\n }\n\n if (this._element.querySelector(Selector.NEXT_PREV)) {\n Util.triggerTransitionEnd(this._element)\n this.cycle(true)\n }\n\n clearInterval(this._interval)\n this._interval = null\n }\n\n cycle(event) {\n if (!event) {\n this._isPaused = false\n }\n\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n\n if (this._config.interval && !this._isPaused) {\n this._interval = setInterval(\n (document.visibilityState ? this.nextWhenVisible : this.next).bind(this),\n this._config.interval\n )\n }\n }\n\n to(index) {\n this._activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n\n const activeIndex = this._getItemIndex(this._activeElement)\n\n if (index > this._items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n $(this._element).one(Event.SLID, () => this.to(index))\n return\n }\n\n if (activeIndex === index) {\n this.pause()\n this.cycle()\n return\n }\n\n const direction = index > activeIndex\n ? Direction.NEXT\n : Direction.PREV\n\n this._slide(direction, this._items[index])\n }\n\n dispose() {\n $(this._element).off(EVENT_KEY)\n $.removeData(this._element, DATA_KEY)\n\n this._items = null\n this._config = null\n this._element = null\n this._interval = null\n this._isPaused = null\n this._isSliding = null\n this._activeElement = null\n this._indicatorsElement = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n $(this._element)\n .on(Event.KEYDOWN, (event) => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n $(this._element)\n .on(Event.MOUSEENTER, (event) => this.pause(event))\n .on(Event.MOUSELEAVE, (event) => this.cycle(event))\n if ('ontouchstart' in document.documentElement) {\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n $(this._element).on(Event.TOUCHEND, () => {\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n })\n }\n }\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n switch (event.which) {\n case ARROW_LEFT_KEYCODE:\n event.preventDefault()\n this.prev()\n break\n case ARROW_RIGHT_KEYCODE:\n event.preventDefault()\n this.next()\n break\n default:\n }\n }\n\n _getItemIndex(element) {\n this._items = element && element.parentNode\n ? [].slice.call(element.parentNode.querySelectorAll(Selector.ITEM))\n : []\n return this._items.indexOf(element)\n }\n\n _getItemByDirection(direction, activeElement) {\n const isNextDirection = direction === Direction.NEXT\n const isPrevDirection = direction === Direction.PREV\n const activeIndex = this._getItemIndex(activeElement)\n const lastItemIndex = this._items.length - 1\n const isGoingToWrap = isPrevDirection && activeIndex === 0 ||\n isNextDirection && activeIndex === lastItemIndex\n\n if (isGoingToWrap && !this._config.wrap) {\n return activeElement\n }\n\n const delta = direction === Direction.PREV ? -1 : 1\n const itemIndex = (activeIndex + delta) % this._items.length\n\n return itemIndex === -1\n ? this._items[this._items.length - 1] : this._items[itemIndex]\n }\n\n _triggerSlideEvent(relatedTarget, eventDirectionName) {\n const targetIndex = this._getItemIndex(relatedTarget)\n const fromIndex = this._getItemIndex(this._element.querySelector(Selector.ACTIVE_ITEM))\n const slideEvent = $.Event(Event.SLIDE, {\n relatedTarget,\n direction: eventDirectionName,\n from: fromIndex,\n to: targetIndex\n })\n\n $(this._element).trigger(slideEvent)\n\n return slideEvent\n }\n\n _setActiveIndicatorElement(element) {\n if (this._indicatorsElement) {\n const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector.ACTIVE))\n $(indicators)\n .removeClass(ClassName.ACTIVE)\n\n const nextIndicator = this._indicatorsElement.children[\n this._getItemIndex(element)\n ]\n\n if (nextIndicator) {\n $(nextIndicator).addClass(ClassName.ACTIVE)\n }\n }\n }\n\n _slide(direction, element) {\n const activeElement = this._element.querySelector(Selector.ACTIVE_ITEM)\n const activeElementIndex = this._getItemIndex(activeElement)\n const nextElement = element || activeElement &&\n this._getItemByDirection(direction, activeElement)\n const nextElementIndex = this._getItemIndex(nextElement)\n const isCycling = Boolean(this._interval)\n\n let directionalClassName\n let orderClassName\n let eventDirectionName\n\n if (direction === Direction.NEXT) {\n directionalClassName = ClassName.LEFT\n orderClassName = ClassName.NEXT\n eventDirectionName = Direction.LEFT\n } else {\n directionalClassName = ClassName.RIGHT\n orderClassName = ClassName.PREV\n eventDirectionName = Direction.RIGHT\n }\n\n if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {\n this._isSliding = false\n return\n }\n\n const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)\n if (slideEvent.isDefaultPrevented()) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n return\n }\n\n this._isSliding = true\n\n if (isCycling) {\n this.pause()\n }\n\n this._setActiveIndicatorElement(nextElement)\n\n const slidEvent = $.Event(Event.SLID, {\n relatedTarget: nextElement,\n direction: eventDirectionName,\n from: activeElementIndex,\n to: nextElementIndex\n })\n\n if ($(this._element).hasClass(ClassName.SLIDE)) {\n $(nextElement).addClass(orderClassName)\n\n Util.reflow(nextElement)\n\n $(activeElement).addClass(directionalClassName)\n $(nextElement).addClass(directionalClassName)\n\n const transitionDuration = Util.getTransitionDurationFromElement(activeElement)\n\n $(activeElement)\n .one(Util.TRANSITION_END, () => {\n $(nextElement)\n .removeClass(`${directionalClassName} ${orderClassName}`)\n .addClass(ClassName.ACTIVE)\n\n $(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)\n\n this._isSliding = false\n\n setTimeout(() => $(this._element).trigger(slidEvent), 0)\n })\n .emulateTransitionEnd(transitionDuration)\n } else {\n $(activeElement).removeClass(ClassName.ACTIVE)\n $(nextElement).addClass(ClassName.ACTIVE)\n\n this._isSliding = false\n $(this._element).trigger(slidEvent)\n }\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n let _config = {\n ...Default,\n ...$(this).data()\n }\n\n if (typeof config === 'object') {\n _config = {\n ..._config,\n ...config\n }\n }\n\n const action = typeof config === 'string' ? config : _config.slide\n\n if (!data) {\n data = new Carousel(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'number') {\n data.to(config)\n } else if (typeof action === 'string') {\n if (typeof data[action] === 'undefined') {\n throw new TypeError(`No method named \"${action}\"`)\n }\n data[action]()\n } else if (_config.interval) {\n data.pause()\n data.cycle()\n }\n })\n }\n\n static _dataApiClickHandler(event) {\n const selector = Util.getSelectorFromElement(this)\n\n if (!selector) {\n return\n }\n\n const target = $(selector)[0]\n\n if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {\n return\n }\n\n const config = {\n ...$(target).data(),\n ...$(this).data()\n }\n const slideIndex = this.getAttribute('data-slide-to')\n\n if (slideIndex) {\n config.interval = false\n }\n\n Carousel._jQueryInterface.call($(target), config)\n\n if (slideIndex) {\n $(target).data(DATA_KEY).to(slideIndex)\n }\n\n event.preventDefault()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler)\n\n $(window).on(Event.LOAD_DATA_API, () => {\n const carousels = [].slice.call(document.querySelectorAll(Selector.DATA_RIDE))\n for (let i = 0, len = carousels.length; i < len; i++) {\n const $carousel = $(carousels[i])\n Carousel._jQueryInterface.call($carousel, $carousel.data())\n }\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Carousel._jQueryInterface\n $.fn[NAME].Constructor = Carousel\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Carousel._jQueryInterface\n }\n\n return Carousel\n})($)\n\nexport default Carousel\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Collapse = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'collapse'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.collapse'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Default = {\n toggle : true,\n parent : ''\n }\n\n const DefaultType = {\n toggle : 'boolean',\n parent : '(string|element)'\n }\n\n const Event = {\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SHOW : 'show',\n COLLAPSE : 'collapse',\n COLLAPSING : 'collapsing',\n COLLAPSED : 'collapsed'\n }\n\n const Dimension = {\n WIDTH : 'width',\n HEIGHT : 'height'\n }\n\n const Selector = {\n ACTIVES : '.show, .collapsing',\n DATA_TOGGLE : '[data-toggle=\"collapse\"]'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Collapse {\n constructor(element, config) {\n this._isTransitioning = false\n this._element = element\n this._config = this._getConfig(config)\n this._triggerArray = $.makeArray(document.querySelectorAll(\n `[data-toggle=\"collapse\"][href=\"#${element.id}\"],` +\n `[data-toggle=\"collapse\"][data-target=\"#${element.id}\"]`\n ))\n const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggleList.length; i < len; i++) {\n const elem = toggleList[i]\n const selector = Util.getSelectorFromElement(elem)\n const filterElement = [].slice.call(document.querySelectorAll(selector))\n .filter((foundElem) => foundElem === element)\n\n if (selector !== null && filterElement.length > 0) {\n this._selector = selector\n this._triggerArray.push(elem)\n }\n }\n\n this._parent = this._config.parent ? this._getParent() : null\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._element, this._triggerArray)\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle() {\n if ($(this._element).hasClass(ClassName.SHOW)) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning ||\n $(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n let actives\n let activesData\n\n if (this._parent) {\n actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))\n .filter((elem) => elem.getAttribute('data-parent') === this._config.parent)\n\n if (actives.length === 0) {\n actives = null\n }\n }\n\n if (actives) {\n activesData = $(actives).not(this._selector).data(DATA_KEY)\n if (activesData && activesData._isTransitioning) {\n return\n }\n }\n\n const startEvent = $.Event(Event.SHOW)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n if (actives) {\n Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')\n if (!activesData) {\n $(actives).data(DATA_KEY, null)\n }\n }\n\n const dimension = this._getDimension()\n\n $(this._element)\n .removeClass(ClassName.COLLAPSE)\n .addClass(ClassName.COLLAPSING)\n\n this._element.style[dimension] = 0\n\n if (this._triggerArray.length) {\n $(this._triggerArray)\n .removeClass(ClassName.COLLAPSED)\n .attr('aria-expanded', true)\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .addClass(ClassName.SHOW)\n\n this._element.style[dimension] = ''\n\n this.setTransitioning(false)\n\n $(this._element).trigger(Event.SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning ||\n !$(this._element).hasClass(ClassName.SHOW)) {\n return\n }\n\n const startEvent = $.Event(Event.HIDE)\n $(this._element).trigger(startEvent)\n if (startEvent.isDefaultPrevented()) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n Util.reflow(this._element)\n\n $(this._element)\n .addClass(ClassName.COLLAPSING)\n .removeClass(ClassName.COLLAPSE)\n .removeClass(ClassName.SHOW)\n\n const triggerArrayLength = this._triggerArray.length\n if (triggerArrayLength > 0) {\n for (let i = 0; i < triggerArrayLength; i++) {\n const trigger = this._triggerArray[i]\n const selector = Util.getSelectorFromElement(trigger)\n if (selector !== null) {\n const $elem = $([].slice.call(document.querySelectorAll(selector)))\n if (!$elem.hasClass(ClassName.SHOW)) {\n $(trigger).addClass(ClassName.COLLAPSED)\n .attr('aria-expanded', false)\n }\n }\n }\n }\n\n this.setTransitioning(true)\n\n const complete = () => {\n this.setTransitioning(false)\n $(this._element)\n .removeClass(ClassName.COLLAPSING)\n .addClass(ClassName.COLLAPSE)\n .trigger(Event.HIDDEN)\n }\n\n this._element.style[dimension] = ''\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n }\n\n setTransitioning(isTransitioning) {\n this._isTransitioning = isTransitioning\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n this._config = null\n this._parent = null\n this._element = null\n this._triggerArray = null\n this._isTransitioning = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n config.toggle = Boolean(config.toggle) // Coerce string values\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _getDimension() {\n const hasWidth = $(this._element).hasClass(Dimension.WIDTH)\n return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT\n }\n\n _getParent() {\n let parent = null\n if (Util.isElement(this._config.parent)) {\n parent = this._config.parent\n\n // It's a jQuery object\n if (typeof this._config.parent.jquery !== 'undefined') {\n parent = this._config.parent[0]\n }\n } else {\n parent = document.querySelector(this._config.parent)\n }\n\n const selector =\n `[data-toggle=\"collapse\"][data-parent=\"${this._config.parent}\"]`\n\n const children = [].slice.call(parent.querySelectorAll(selector))\n $(children).each((i, element) => {\n this._addAriaAndCollapsedClass(\n Collapse._getTargetFromElement(element),\n [element]\n )\n })\n\n return parent\n }\n\n _addAriaAndCollapsedClass(element, triggerArray) {\n if (element) {\n const isOpen = $(element).hasClass(ClassName.SHOW)\n\n if (triggerArray.length) {\n $(triggerArray)\n .toggleClass(ClassName.COLLAPSED, !isOpen)\n .attr('aria-expanded', isOpen)\n }\n }\n }\n\n // Static\n\n static _getTargetFromElement(element) {\n const selector = Util.getSelectorFromElement(element)\n return selector ? document.querySelector(selector) : null\n }\n\n static _jQueryInterface(config) {\n return this.each(function () {\n const $this = $(this)\n let data = $this.data(DATA_KEY)\n const _config = {\n ...Default,\n ...$this.data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data && _config.toggle && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n if (!data) {\n data = new Collapse(this, _config)\n $this.data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.currentTarget.tagName === 'A') {\n event.preventDefault()\n }\n\n const $trigger = $(this)\n const selector = Util.getSelectorFromElement(this)\n const selectors = [].slice.call(document.querySelectorAll(selector))\n $(selectors).each(function () {\n const $target = $(this)\n const data = $target.data(DATA_KEY)\n const config = data ? 'toggle' : $trigger.data()\n Collapse._jQueryInterface.call($target, config)\n })\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Collapse._jQueryInterface\n $.fn[NAME].Constructor = Collapse\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Collapse._jQueryInterface\n }\n\n return Collapse\n})($)\n\nexport default Collapse\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Dropdown = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'dropdown'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.dropdown'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key\n const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key\n const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key\n const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key\n const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)\n const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,\n KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,\n KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DISABLED : 'disabled',\n SHOW : 'show',\n DROPUP : 'dropup',\n DROPRIGHT : 'dropright',\n DROPLEFT : 'dropleft',\n MENURIGHT : 'dropdown-menu-right',\n MENULEFT : 'dropdown-menu-left',\n POSITION_STATIC : 'position-static'\n }\n\n const Selector = {\n DATA_TOGGLE : '[data-toggle=\"dropdown\"]',\n FORM_CHILD : '.dropdown form',\n MENU : '.dropdown-menu',\n NAVBAR_NAV : '.navbar-nav',\n VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n }\n\n const AttachmentMap = {\n TOP : 'top-start',\n TOPEND : 'top-end',\n BOTTOM : 'bottom-start',\n BOTTOMEND : 'bottom-end',\n RIGHT : 'right-start',\n RIGHTEND : 'right-end',\n LEFT : 'left-start',\n LEFTEND : 'left-end'\n }\n\n const Default = {\n offset : 0,\n flip : true,\n boundary : 'scrollParent',\n reference : 'toggle',\n display : 'dynamic'\n }\n\n const DefaultType = {\n offset : '(number|string|function)',\n flip : 'boolean',\n boundary : '(string|element)',\n reference : '(string|element)',\n display : 'string'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Dropdown {\n constructor(element, config) {\n this._element = element\n this._popper = null\n this._config = this._getConfig(config)\n this._menu = this._getMenuElement()\n this._inNavbar = this._detectNavbar()\n\n this._addEventListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n toggle() {\n if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this._element)\n const isActive = $(this._menu).hasClass(ClassName.SHOW)\n\n Dropdown._clearMenus()\n\n if (isActive) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n const showEvent = $.Event(Event.SHOW, relatedTarget)\n\n $(parent).trigger(showEvent)\n\n if (showEvent.isDefaultPrevented()) {\n return\n }\n\n // Disable totally Popper.js for Dropdown in Navbar\n if (!this._inNavbar) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = parent\n } else if (Util.isElement(this._config.reference)) {\n referenceElement = this._config.reference\n\n // Check if it's jQuery element\n if (typeof this._config.reference.jquery !== 'undefined') {\n referenceElement = this._config.reference[0]\n }\n }\n\n // If boundary is not `scrollParent`, then set position to `static`\n // to allow the menu to \"escape\" the scroll parent's boundaries\n // https://github.com/twbs/bootstrap/issues/24251\n if (this._config.boundary !== 'scrollParent') {\n $(parent).addClass(ClassName.POSITION_STATIC)\n }\n this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig())\n }\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement &&\n $(parent).closest(Selector.NAVBAR_NAV).length === 0) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n $(this._menu).toggleClass(ClassName.SHOW)\n $(parent)\n .toggleClass(ClassName.SHOW)\n .trigger($.Event(Event.SHOWN, relatedTarget))\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._element).off(EVENT_KEY)\n this._element = null\n this._menu = null\n if (this._popper !== null) {\n this._popper.destroy()\n this._popper = null\n }\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Private\n\n _addEventListeners() {\n $(this._element).on(Event.CLICK, (event) => {\n event.preventDefault()\n event.stopPropagation()\n this.toggle()\n })\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this._element).data(),\n ...config\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getMenuElement() {\n if (!this._menu) {\n const parent = Dropdown._getParentFromElement(this._element)\n if (parent) {\n this._menu = parent.querySelector(Selector.MENU)\n }\n }\n return this._menu\n }\n\n _getPlacement() {\n const $parentDropdown = $(this._element.parentNode)\n let placement = AttachmentMap.BOTTOM\n\n // Handle dropup\n if ($parentDropdown.hasClass(ClassName.DROPUP)) {\n placement = AttachmentMap.TOP\n if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.TOPEND\n }\n } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) {\n placement = AttachmentMap.RIGHT\n } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) {\n placement = AttachmentMap.LEFT\n } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {\n placement = AttachmentMap.BOTTOMEND\n }\n return placement\n }\n\n _detectNavbar() {\n return $(this._element).closest('.navbar').length > 0\n }\n\n _getPopperConfig() {\n const offsetConf = {}\n if (typeof this._config.offset === 'function') {\n offsetConf.fn = (data) => {\n data.offsets = {\n ...data.offsets,\n ...this._config.offset(data.offsets) || {}\n }\n return data\n }\n } else {\n offsetConf.offset = this._config.offset\n }\n\n const popperConfig = {\n placement: this._getPlacement(),\n modifiers: {\n offset: offsetConf,\n flip: {\n enabled: this._config.flip\n },\n preventOverflow: {\n boundariesElement: this._config.boundary\n }\n }\n }\n\n // Disable Popper.js if we have a static display\n if (this._config.display === 'static') {\n popperConfig.modifiers.applyStyle = {\n enabled: false\n }\n }\n return popperConfig\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data) {\n data = new Dropdown(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n\n static _clearMenus(event) {\n if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||\n event.type === 'keyup' && event.which !== TAB_KEYCODE)) {\n return\n }\n\n const toggles = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))\n for (let i = 0, len = toggles.length; i < len; i++) {\n const parent = Dropdown._getParentFromElement(toggles[i])\n const context = $(toggles[i]).data(DATA_KEY)\n const relatedTarget = {\n relatedTarget: toggles[i]\n }\n\n if (event && event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n if (!context) {\n continue\n }\n\n const dropdownMenu = context._menu\n if (!$(parent).hasClass(ClassName.SHOW)) {\n continue\n }\n\n if (event && (event.type === 'click' &&\n /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) &&\n $.contains(parent, event.target)) {\n continue\n }\n\n const hideEvent = $.Event(Event.HIDE, relatedTarget)\n $(parent).trigger(hideEvent)\n if (hideEvent.isDefaultPrevented()) {\n continue\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n toggles[i].setAttribute('aria-expanded', 'false')\n\n $(dropdownMenu).removeClass(ClassName.SHOW)\n $(parent)\n .removeClass(ClassName.SHOW)\n .trigger($.Event(Event.HIDDEN, relatedTarget))\n }\n }\n\n static _getParentFromElement(element) {\n let parent\n const selector = Util.getSelectorFromElement(element)\n\n if (selector) {\n parent = document.querySelector(selector)\n }\n\n return parent || element.parentNode\n }\n\n // eslint-disable-next-line complexity\n static _dataApiKeydownHandler(event) {\n // If not input/textarea:\n // - And not a key in REGEXP_KEYDOWN => not a dropdown command\n // If input/textarea:\n // - If space key => not a dropdown command\n // - If key is other than escape\n // - If key is not up or down => not a dropdown command\n // - If trigger inside the menu => not a dropdown command\n if (/input|textarea/i.test(event.target.tagName)\n ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE &&\n (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE ||\n $(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {\n return\n }\n\n event.preventDefault()\n event.stopPropagation()\n\n if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n return\n }\n\n const parent = Dropdown._getParentFromElement(this)\n const isActive = $(parent).hasClass(ClassName.SHOW)\n\n if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) ||\n isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {\n if (event.which === ESCAPE_KEYCODE) {\n const toggle = parent.querySelector(Selector.DATA_TOGGLE)\n $(toggle).trigger('focus')\n }\n\n $(this).trigger('click')\n return\n }\n\n const items = [].slice.call(parent.querySelectorAll(Selector.VISIBLE_ITEMS))\n\n if (items.length === 0) {\n return\n }\n\n let index = items.indexOf(event.target)\n\n if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up\n index--\n }\n\n if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down\n index++\n }\n\n if (index < 0) {\n index = 0\n }\n\n items[index].focus()\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document)\n .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)\n .on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler)\n .on(`${Event.CLICK_DATA_API} ${Event.KEYUP_DATA_API}`, Dropdown._clearMenus)\n .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n event.preventDefault()\n event.stopPropagation()\n Dropdown._jQueryInterface.call($(this), 'toggle')\n })\n .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {\n e.stopPropagation()\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Dropdown._jQueryInterface\n $.fn[NAME].Constructor = Dropdown\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Dropdown._jQueryInterface\n }\n\n return Dropdown\n})($, Popper)\n\nexport default Dropdown\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Modal = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'modal'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.modal'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key\n\n const Default = {\n backdrop : true,\n keyboard : true,\n focus : true,\n show : true\n }\n\n const DefaultType = {\n backdrop : '(boolean|string)',\n keyboard : 'boolean',\n focus : 'boolean',\n show : 'boolean'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n RESIZE : `resize${EVENT_KEY}`,\n CLICK_DISMISS : `click.dismiss${EVENT_KEY}`,\n KEYDOWN_DISMISS : `keydown.dismiss${EVENT_KEY}`,\n MOUSEUP_DISMISS : `mouseup.dismiss${EVENT_KEY}`,\n MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,\n CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n SCROLLBAR_MEASURER : 'modal-scrollbar-measure',\n BACKDROP : 'modal-backdrop',\n OPEN : 'modal-open',\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n DIALOG : '.modal-dialog',\n DATA_TOGGLE : '[data-toggle=\"modal\"]',\n DATA_DISMISS : '[data-dismiss=\"modal\"]',\n FIXED_CONTENT : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',\n STICKY_CONTENT : '.sticky-top'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Modal {\n constructor(element, config) {\n this._config = this._getConfig(config)\n this._element = element\n this._dialog = element.querySelector(Selector.DIALOG)\n this._backdrop = null\n this._isShown = false\n this._isBodyOverflowing = false\n this._ignoreBackdropClick = false\n this._scrollbarWidth = 0\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isTransitioning || this._isShown) {\n return\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n this._isTransitioning = true\n }\n\n const showEvent = $.Event(Event.SHOW, {\n relatedTarget\n })\n\n $(this._element).trigger(showEvent)\n\n if (this._isShown || showEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = true\n\n this._checkScrollbar()\n this._setScrollbar()\n\n this._adjustDialog()\n\n $(document.body).addClass(ClassName.OPEN)\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(this._element).on(\n Event.CLICK_DISMISS,\n Selector.DATA_DISMISS,\n (event) => this.hide(event)\n )\n\n $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {\n $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {\n if ($(event.target).is(this._element)) {\n this._ignoreBackdropClick = true\n }\n })\n })\n\n this._showBackdrop(() => this._showElement(relatedTarget))\n }\n\n hide(event) {\n if (event) {\n event.preventDefault()\n }\n\n if (this._isTransitioning || !this._isShown) {\n return\n }\n\n const hideEvent = $.Event(Event.HIDE)\n\n $(this._element).trigger(hideEvent)\n\n if (!this._isShown || hideEvent.isDefaultPrevented()) {\n return\n }\n\n this._isShown = false\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (transition) {\n this._isTransitioning = true\n }\n\n this._setEscapeEvent()\n this._setResizeEvent()\n\n $(document).off(Event.FOCUSIN)\n\n $(this._element).removeClass(ClassName.SHOW)\n\n $(this._element).off(Event.CLICK_DISMISS)\n $(this._dialog).off(Event.MOUSEDOWN_DISMISS)\n\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._element)\n .one(Util.TRANSITION_END, (event) => this._hideModal(event))\n .emulateTransitionEnd(transitionDuration)\n } else {\n this._hideModal()\n }\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n\n $(window, document, this._element, this._backdrop).off(EVENT_KEY)\n\n this._config = null\n this._element = null\n this._dialog = null\n this._backdrop = null\n this._isShown = null\n this._isBodyOverflowing = null\n this._ignoreBackdropClick = null\n this._scrollbarWidth = null\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...config\n }\n Util.typeCheckConfig(NAME, config, DefaultType)\n return config\n }\n\n _showElement(relatedTarget) {\n const transition = $(this._element).hasClass(ClassName.FADE)\n\n if (!this._element.parentNode ||\n this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n // Don't move modal's DOM position\n document.body.appendChild(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.scrollTop = 0\n\n if (transition) {\n Util.reflow(this._element)\n }\n\n $(this._element).addClass(ClassName.SHOW)\n\n if (this._config.focus) {\n this._enforceFocus()\n }\n\n const shownEvent = $.Event(Event.SHOWN, {\n relatedTarget\n })\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._element.focus()\n }\n this._isTransitioning = false\n $(this._element).trigger(shownEvent)\n }\n\n if (transition) {\n const transitionDuration = Util.getTransitionDurationFromElement(this._element)\n\n $(this._dialog)\n .one(Util.TRANSITION_END, transitionComplete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n transitionComplete()\n }\n }\n\n _enforceFocus() {\n $(document)\n .off(Event.FOCUSIN) // Guard against infinite focus loop\n .on(Event.FOCUSIN, (event) => {\n if (document !== event.target &&\n this._element !== event.target &&\n $(this._element).has(event.target).length === 0) {\n this._element.focus()\n }\n })\n }\n\n _setEscapeEvent() {\n if (this._isShown && this._config.keyboard) {\n $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {\n if (event.which === ESCAPE_KEYCODE) {\n event.preventDefault()\n this.hide()\n }\n })\n } else if (!this._isShown) {\n $(this._element).off(Event.KEYDOWN_DISMISS)\n }\n }\n\n _setResizeEvent() {\n if (this._isShown) {\n $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))\n } else {\n $(window).off(Event.RESIZE)\n }\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._isTransitioning = false\n this._showBackdrop(() => {\n $(document.body).removeClass(ClassName.OPEN)\n this._resetAdjustments()\n this._resetScrollbar()\n $(this._element).trigger(Event.HIDDEN)\n })\n }\n\n _removeBackdrop() {\n if (this._backdrop) {\n $(this._backdrop).remove()\n this._backdrop = null\n }\n }\n\n _showBackdrop(callback) {\n const animate = $(this._element).hasClass(ClassName.FADE)\n ? ClassName.FADE : ''\n\n if (this._isShown && this._config.backdrop) {\n this._backdrop = document.createElement('div')\n this._backdrop.className = ClassName.BACKDROP\n\n if (animate) {\n this._backdrop.classList.add(animate)\n }\n\n $(this._backdrop).appendTo(document.body)\n\n $(this._element).on(Event.CLICK_DISMISS, (event) => {\n if (this._ignoreBackdropClick) {\n this._ignoreBackdropClick = false\n return\n }\n if (event.target !== event.currentTarget) {\n return\n }\n if (this._config.backdrop === 'static') {\n this._element.focus()\n } else {\n this.hide()\n }\n })\n\n if (animate) {\n Util.reflow(this._backdrop)\n }\n\n $(this._backdrop).addClass(ClassName.SHOW)\n\n if (!callback) {\n return\n }\n\n if (!animate) {\n callback()\n return\n }\n\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callback)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else if (!this._isShown && this._backdrop) {\n $(this._backdrop).removeClass(ClassName.SHOW)\n\n const callbackRemove = () => {\n this._removeBackdrop()\n if (callback) {\n callback()\n }\n }\n\n if ($(this._element).hasClass(ClassName.FADE)) {\n const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)\n\n $(this._backdrop)\n .one(Util.TRANSITION_END, callbackRemove)\n .emulateTransitionEnd(backdropTransitionDuration)\n } else {\n callbackRemove()\n }\n } else if (callback) {\n callback()\n }\n }\n\n // ----------------------------------------------------------------------\n // the following methods are used to handle overflowing modals\n // todo (fat): these should probably be refactored out of modal.js\n // ----------------------------------------------------------------------\n\n _adjustDialog() {\n const isModalOverflowing =\n this._element.scrollHeight > document.documentElement.clientHeight\n\n if (!this._isBodyOverflowing && isModalOverflowing) {\n this._element.style.paddingLeft = `${this._scrollbarWidth}px`\n }\n\n if (this._isBodyOverflowing && !isModalOverflowing) {\n this._element.style.paddingRight = `${this._scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n _checkScrollbar() {\n const rect = document.body.getBoundingClientRect()\n this._isBodyOverflowing = rect.left + rect.right < window.innerWidth\n this._scrollbarWidth = this._getScrollbarWidth()\n }\n\n _setScrollbar() {\n if (this._isBodyOverflowing) {\n // Note: DOMNode.style.paddingRight returns the actual value or '' if not set\n // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))\n\n // Adjust fixed content padding\n $(fixedContent).each((index, element) => {\n const actualPadding = element.style.paddingRight\n const calculatedPadding = $(element).css('padding-right')\n $(element)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n })\n\n // Adjust sticky content margin\n $(stickyContent).each((index, element) => {\n const actualMargin = element.style.marginRight\n const calculatedMargin = $(element).css('margin-right')\n $(element)\n .data('margin-right', actualMargin)\n .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)\n })\n\n // Adjust body padding\n const actualPadding = document.body.style.paddingRight\n const calculatedPadding = $(document.body).css('padding-right')\n $(document.body)\n .data('padding-right', actualPadding)\n .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)\n }\n }\n\n _resetScrollbar() {\n // Restore fixed content padding\n const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))\n $(fixedContent).each((index, element) => {\n const padding = $(element).data('padding-right')\n $(element).removeData('padding-right')\n element.style.paddingRight = padding ? padding : ''\n })\n\n // Restore sticky content\n const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))\n $(elements).each((index, element) => {\n const margin = $(element).data('margin-right')\n if (typeof margin !== 'undefined') {\n $(element).css('margin-right', margin).removeData('margin-right')\n }\n })\n\n // Restore body padding\n const padding = $(document.body).data('padding-right')\n $(document.body).removeData('padding-right')\n document.body.style.paddingRight = padding ? padding : ''\n }\n\n _getScrollbarWidth() { // thx d.walsh\n const scrollDiv = document.createElement('div')\n scrollDiv.className = ClassName.SCROLLBAR_MEASURER\n document.body.appendChild(scrollDiv)\n const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth\n document.body.removeChild(scrollDiv)\n return scrollbarWidth\n }\n\n // Static\n\n static _jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = {\n ...Default,\n ...$(this).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (!data) {\n data = new Modal(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config](relatedTarget)\n } else if (_config.show) {\n data.show(relatedTarget)\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {\n let target\n const selector = Util.getSelectorFromElement(this)\n\n if (selector) {\n target = document.querySelector(selector)\n }\n\n const config = $(target).data(DATA_KEY)\n ? 'toggle' : {\n ...$(target).data(),\n ...$(this).data()\n }\n\n if (this.tagName === 'A' || this.tagName === 'AREA') {\n event.preventDefault()\n }\n\n const $target = $(target).one(Event.SHOW, (showEvent) => {\n if (showEvent.isDefaultPrevented()) {\n // Only register focus restorer if modal will actually get shown\n return\n }\n\n $target.one(Event.HIDDEN, () => {\n if ($(this).is(':visible')) {\n this.focus()\n }\n })\n })\n\n Modal._jQueryInterface.call($(target), config, this)\n })\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Modal._jQueryInterface\n $.fn[NAME].Constructor = Modal\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Modal._jQueryInterface\n }\n\n return Modal\n})($)\n\nexport default Modal\n","import $ from 'jquery'\nimport Popper from 'popper.js'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Tooltip = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'tooltip'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.tooltip'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const CLASS_PREFIX = 'bs-tooltip'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const DefaultType = {\n animation : 'boolean',\n template : 'string',\n title : '(string|element|function)',\n trigger : 'string',\n delay : '(number|object)',\n html : 'boolean',\n selector : '(string|boolean)',\n placement : '(string|function)',\n offset : '(number|string)',\n container : '(string|element|boolean)',\n fallbackPlacement : '(string|array)',\n boundary : '(string|element)'\n }\n\n const AttachmentMap = {\n AUTO : 'auto',\n TOP : 'top',\n RIGHT : 'right',\n BOTTOM : 'bottom',\n LEFT : 'left'\n }\n\n const Default = {\n animation : true,\n template : '
' +\n '
' +\n '
',\n trigger : 'hover focus',\n title : '',\n delay : 0,\n html : false,\n selector : false,\n placement : 'top',\n offset : 0,\n container : false,\n fallbackPlacement : 'flip',\n boundary : 'scrollParent'\n }\n\n const HoverState = {\n SHOW : 'show',\n OUT : 'out'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TOOLTIP : '.tooltip',\n TOOLTIP_INNER : '.tooltip-inner',\n ARROW : '.arrow'\n }\n\n const Trigger = {\n HOVER : 'hover',\n FOCUS : 'focus',\n CLICK : 'click',\n MANUAL : 'manual'\n }\n\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Tooltip {\n constructor(element, config) {\n /**\n * Check for Popper dependency\n * Popper - https://popper.js.org\n */\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)')\n }\n\n // private\n this._isEnabled = true\n this._timeout = 0\n this._hoverState = ''\n this._activeTrigger = {}\n this._popper = null\n\n // Protected\n this.element = element\n this.config = this._getConfig(config)\n this.tip = null\n\n this._setListeners()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Public\n\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle(event) {\n if (!this._isEnabled) {\n return\n }\n\n if (event) {\n const dataKey = this.constructor.DATA_KEY\n let context = $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n context._activeTrigger.click = !context._activeTrigger.click\n\n if (context._isWithActiveTrigger()) {\n context._enter(null, context)\n } else {\n context._leave(null, context)\n }\n } else {\n if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {\n this._leave(null, this)\n return\n }\n\n this._enter(null, this)\n }\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n $.removeData(this.element, this.constructor.DATA_KEY)\n\n $(this.element).off(this.constructor.EVENT_KEY)\n $(this.element).closest('.modal').off('hide.bs.modal')\n\n if (this.tip) {\n $(this.tip).remove()\n }\n\n this._isEnabled = null\n this._timeout = null\n this._hoverState = null\n this._activeTrigger = null\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n this._popper = null\n this.element = null\n this.config = null\n this.tip = null\n }\n\n show() {\n if ($(this.element).css('display') === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n const showEvent = $.Event(this.constructor.Event.SHOW)\n if (this.isWithContent() && this._isEnabled) {\n $(this.element).trigger(showEvent)\n\n const isInTheDom = $.contains(\n this.element.ownerDocument.documentElement,\n this.element\n )\n\n if (showEvent.isDefaultPrevented() || !isInTheDom) {\n return\n }\n\n const tip = this.getTipElement()\n const tipId = Util.getUID(this.constructor.NAME)\n\n tip.setAttribute('id', tipId)\n this.element.setAttribute('aria-describedby', tipId)\n\n this.setContent()\n\n if (this.config.animation) {\n $(tip).addClass(ClassName.FADE)\n }\n\n const placement = typeof this.config.placement === 'function'\n ? this.config.placement.call(this, tip, this.element)\n : this.config.placement\n\n const attachment = this._getAttachment(placement)\n this.addAttachmentClass(attachment)\n\n const container = this.config.container === false ? document.body : $(document).find(this.config.container)\n\n $(tip).data(this.constructor.DATA_KEY, this)\n\n if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {\n $(tip).appendTo(container)\n }\n\n $(this.element).trigger(this.constructor.Event.INSERTED)\n\n this._popper = new Popper(this.element, tip, {\n placement: attachment,\n modifiers: {\n offset: {\n offset: this.config.offset\n },\n flip: {\n behavior: this.config.fallbackPlacement\n },\n arrow: {\n element: Selector.ARROW\n },\n preventOverflow: {\n boundariesElement: this.config.boundary\n }\n },\n onCreate: (data) => {\n if (data.originalPlacement !== data.placement) {\n this._handlePopperPlacementChange(data)\n }\n },\n onUpdate: (data) => {\n this._handlePopperPlacementChange(data)\n }\n })\n\n $(tip).addClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().on('mouseover', null, $.noop)\n }\n\n const complete = () => {\n if (this.config.animation) {\n this._fixTransition()\n }\n const prevHoverState = this._hoverState\n this._hoverState = null\n\n $(this.element).trigger(this.constructor.Event.SHOWN)\n\n if (prevHoverState === HoverState.OUT) {\n this._leave(null, this)\n }\n }\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(this.tip)\n\n $(this.tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n }\n }\n\n hide(callback) {\n const tip = this.getTipElement()\n const hideEvent = $.Event(this.constructor.Event.HIDE)\n const complete = () => {\n if (this._hoverState !== HoverState.SHOW && tip.parentNode) {\n tip.parentNode.removeChild(tip)\n }\n\n this._cleanTipClass()\n this.element.removeAttribute('aria-describedby')\n $(this.element).trigger(this.constructor.Event.HIDDEN)\n if (this._popper !== null) {\n this._popper.destroy()\n }\n\n if (callback) {\n callback()\n }\n }\n\n $(this.element).trigger(hideEvent)\n\n if (hideEvent.isDefaultPrevented()) {\n return\n }\n\n $(tip).removeClass(ClassName.SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n $(document.body).children().off('mouseover', null, $.noop)\n }\n\n this._activeTrigger[Trigger.CLICK] = false\n this._activeTrigger[Trigger.FOCUS] = false\n this._activeTrigger[Trigger.HOVER] = false\n\n if ($(this.tip).hasClass(ClassName.FADE)) {\n const transitionDuration = Util.getTransitionDurationFromElement(tip)\n\n $(tip)\n .one(Util.TRANSITION_END, complete)\n .emulateTransitionEnd(transitionDuration)\n } else {\n complete()\n }\n\n this._hoverState = ''\n }\n\n update() {\n if (this._popper !== null) {\n this._popper.scheduleUpdate()\n }\n }\n\n // Protected\n\n isWithContent() {\n return Boolean(this.getTitle())\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const tip = this.getTipElement()\n this.setElementContent($(tip.querySelectorAll(Selector.TOOLTIP_INNER)), this.getTitle())\n $(tip).removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n setElementContent($element, content) {\n const html = this.config.html\n if (typeof content === 'object' && (content.nodeType || content.jquery)) {\n // Content is a DOM node or a jQuery\n if (html) {\n if (!$(content).parent().is($element)) {\n $element.empty().append(content)\n }\n } else {\n $element.text($(content).text())\n }\n } else {\n $element[html ? 'html' : 'text'](content)\n }\n }\n\n getTitle() {\n let title = this.element.getAttribute('data-original-title')\n\n if (!title) {\n title = typeof this.config.title === 'function'\n ? this.config.title.call(this.element)\n : this.config.title\n }\n\n return title\n }\n\n // Private\n\n _getAttachment(placement) {\n return AttachmentMap[placement.toUpperCase()]\n }\n\n _setListeners() {\n const triggers = this.config.trigger.split(' ')\n\n triggers.forEach((trigger) => {\n if (trigger === 'click') {\n $(this.element).on(\n this.constructor.Event.CLICK,\n this.config.selector,\n (event) => this.toggle(event)\n )\n } else if (trigger !== Trigger.MANUAL) {\n const eventIn = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSEENTER\n : this.constructor.Event.FOCUSIN\n const eventOut = trigger === Trigger.HOVER\n ? this.constructor.Event.MOUSELEAVE\n : this.constructor.Event.FOCUSOUT\n\n $(this.element)\n .on(\n eventIn,\n this.config.selector,\n (event) => this._enter(event)\n )\n .on(\n eventOut,\n this.config.selector,\n (event) => this._leave(event)\n )\n }\n\n $(this.element).closest('.modal').on(\n 'hide.bs.modal',\n () => this.hide()\n )\n })\n\n if (this.config.selector) {\n this.config = {\n ...this.config,\n trigger: 'manual',\n selector: ''\n }\n } else {\n this._fixTitle()\n }\n }\n\n _fixTitle() {\n const titleType = typeof this.element.getAttribute('data-original-title')\n if (this.element.getAttribute('title') ||\n titleType !== 'string') {\n this.element.setAttribute(\n 'data-original-title',\n this.element.getAttribute('title') || ''\n )\n this.element.setAttribute('title', '')\n }\n }\n\n _enter(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER\n ] = true\n }\n\n if ($(context.getTipElement()).hasClass(ClassName.SHOW) ||\n context._hoverState === HoverState.SHOW) {\n context._hoverState = HoverState.SHOW\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.SHOW\n\n if (!context.config.delay || !context.config.delay.show) {\n context.show()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.SHOW) {\n context.show()\n }\n }, context.config.delay.show)\n }\n\n _leave(event, context) {\n const dataKey = this.constructor.DATA_KEY\n\n context = context || $(event.currentTarget).data(dataKey)\n\n if (!context) {\n context = new this.constructor(\n event.currentTarget,\n this._getDelegateConfig()\n )\n $(event.currentTarget).data(dataKey, context)\n }\n\n if (event) {\n context._activeTrigger[\n event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER\n ] = false\n }\n\n if (context._isWithActiveTrigger()) {\n return\n }\n\n clearTimeout(context._timeout)\n\n context._hoverState = HoverState.OUT\n\n if (!context.config.delay || !context.config.delay.hide) {\n context.hide()\n return\n }\n\n context._timeout = setTimeout(() => {\n if (context._hoverState === HoverState.OUT) {\n context.hide()\n }\n }, context.config.delay.hide)\n }\n\n _isWithActiveTrigger() {\n for (const trigger in this._activeTrigger) {\n if (this._activeTrigger[trigger]) {\n return true\n }\n }\n\n return false\n }\n\n _getConfig(config) {\n config = {\n ...this.constructor.Default,\n ...$(this.element).data(),\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n Util.typeCheckConfig(\n NAME,\n config,\n this.constructor.DefaultType\n )\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n if (this.config) {\n for (const key in this.config) {\n if (this.constructor.Default[key] !== this.config[key]) {\n config[key] = this.config[key]\n }\n }\n }\n\n return config\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n _handlePopperPlacementChange(popperData) {\n const popperInstance = popperData.instance\n this.tip = popperInstance.popper\n this._cleanTipClass()\n this.addAttachmentClass(this._getAttachment(popperData.placement))\n }\n\n _fixTransition() {\n const tip = this.getTipElement()\n const initConfigAnimation = this.config.animation\n if (tip.getAttribute('x-placement') !== null) {\n return\n }\n $(tip).removeClass(ClassName.FADE)\n this.config.animation = false\n this.hide()\n this.show()\n this.config.animation = initConfigAnimation\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' && config\n\n if (!data && /dispose|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Tooltip(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Tooltip._jQueryInterface\n $.fn[NAME].Constructor = Tooltip\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Tooltip._jQueryInterface\n }\n\n return Tooltip\n})($, Popper)\n\nexport default Tooltip\n","import $ from 'jquery'\nimport Tooltip from './tooltip'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Popover = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'popover'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.popover'\n const EVENT_KEY = `.${DATA_KEY}`\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n const CLASS_PREFIX = 'bs-popover'\n const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\\\s)${CLASS_PREFIX}\\\\S+`, 'g')\n\n const Default = {\n ...Tooltip.Default,\n placement : 'right',\n trigger : 'click',\n content : '',\n template : '
' +\n '
' +\n '

' +\n '
'\n }\n\n const DefaultType = {\n ...Tooltip.DefaultType,\n content : '(string|element|function)'\n }\n\n const ClassName = {\n FADE : 'fade',\n SHOW : 'show'\n }\n\n const Selector = {\n TITLE : '.popover-header',\n CONTENT : '.popover-body'\n }\n\n const Event = {\n HIDE : `hide${EVENT_KEY}`,\n HIDDEN : `hidden${EVENT_KEY}`,\n SHOW : `show${EVENT_KEY}`,\n SHOWN : `shown${EVENT_KEY}`,\n INSERTED : `inserted${EVENT_KEY}`,\n CLICK : `click${EVENT_KEY}`,\n FOCUSIN : `focusin${EVENT_KEY}`,\n FOCUSOUT : `focusout${EVENT_KEY}`,\n MOUSEENTER : `mouseenter${EVENT_KEY}`,\n MOUSELEAVE : `mouseleave${EVENT_KEY}`\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class Popover extends Tooltip {\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n static get NAME() {\n return NAME\n }\n\n static get DATA_KEY() {\n return DATA_KEY\n }\n\n static get Event() {\n return Event\n }\n\n static get EVENT_KEY() {\n return EVENT_KEY\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n // Overrides\n\n isWithContent() {\n return this.getTitle() || this._getContent()\n }\n\n addAttachmentClass(attachment) {\n $(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`)\n }\n\n getTipElement() {\n this.tip = this.tip || $(this.config.template)[0]\n return this.tip\n }\n\n setContent() {\n const $tip = $(this.getTipElement())\n\n // We use append for html objects to maintain js events\n this.setElementContent($tip.find(Selector.TITLE), this.getTitle())\n let content = this._getContent()\n if (typeof content === 'function') {\n content = content.call(this.element)\n }\n this.setElementContent($tip.find(Selector.CONTENT), content)\n\n $tip.removeClass(`${ClassName.FADE} ${ClassName.SHOW}`)\n }\n\n // Private\n\n _getContent() {\n return this.element.getAttribute('data-content') ||\n this.config.content\n }\n\n _cleanTipClass() {\n const $tip = $(this.getTipElement())\n const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX)\n if (tabClass !== null && tabClass.length > 0) {\n $tip.removeClass(tabClass.join(''))\n }\n }\n\n // Static\n\n static _jQueryInterface(config) {\n return this.each(function () {\n let data = $(this).data(DATA_KEY)\n const _config = typeof config === 'object' ? config : null\n\n if (!data && /destroy|hide/.test(config)) {\n return\n }\n\n if (!data) {\n data = new Popover(this, _config)\n $(this).data(DATA_KEY, data)\n }\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n data[config]()\n }\n })\n }\n }\n\n /**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\n $.fn[NAME] = Popover._jQueryInterface\n $.fn[NAME].Constructor = Popover\n $.fn[NAME].noConflict = function () {\n $.fn[NAME] = JQUERY_NO_CONFLICT\n return Popover._jQueryInterface\n }\n\n return Popover\n})($)\n\nexport default Popover\n","import $ from 'jquery'\nimport Util from './util'\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.1.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst ScrollSpy = (($) => {\n /**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\n const NAME = 'scrollspy'\n const VERSION = '4.1.3'\n const DATA_KEY = 'bs.scrollspy'\n const EVENT_KEY = `.${DATA_KEY}`\n const DATA_API_KEY = '.data-api'\n const JQUERY_NO_CONFLICT = $.fn[NAME]\n\n const Default = {\n offset : 10,\n method : 'auto',\n target : ''\n }\n\n const DefaultType = {\n offset : 'number',\n method : 'string',\n target : '(string|element)'\n }\n\n const Event = {\n ACTIVATE : `activate${EVENT_KEY}`,\n SCROLL : `scroll${EVENT_KEY}`,\n LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`\n }\n\n const ClassName = {\n DROPDOWN_ITEM : 'dropdown-item',\n DROPDOWN_MENU : 'dropdown-menu',\n ACTIVE : 'active'\n }\n\n const Selector = {\n DATA_SPY : '[data-spy=\"scroll\"]',\n ACTIVE : '.active',\n NAV_LIST_GROUP : '.nav, .list-group',\n NAV_LINKS : '.nav-link',\n NAV_ITEMS : '.nav-item',\n LIST_ITEMS : '.list-group-item',\n DROPDOWN : '.dropdown',\n DROPDOWN_ITEMS : '.dropdown-item',\n DROPDOWN_TOGGLE : '.dropdown-toggle'\n }\n\n const OffsetMethod = {\n OFFSET : 'offset',\n POSITION : 'position'\n }\n\n /**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\n class ScrollSpy {\n constructor(element, config) {\n this._element = element\n this._scrollElement = element.tagName === 'BODY' ? window : element\n this._config = this._getConfig(config)\n this._selector = `${this._config.target} ${Selector.NAV_LINKS},` +\n `${this._config.target} ${Selector.LIST_ITEMS},` +\n `${this._config.target} ${Selector.DROPDOWN_ITEMS}`\n this._offsets = []\n this._targets = []\n this._activeTarget = null\n this._scrollHeight = 0\n\n $(this._scrollElement).on(Event.SCROLL, (event) => this._process(event))\n\n this.refresh()\n this._process()\n }\n\n // Getters\n\n static get VERSION() {\n return VERSION\n }\n\n static get Default() {\n return Default\n }\n\n // Public\n\n refresh() {\n const autoMethod = this._scrollElement === this._scrollElement.window\n ? OffsetMethod.OFFSET : OffsetMethod.POSITION\n\n const offsetMethod = this._config.method === 'auto'\n ? autoMethod : this._config.method\n\n const offsetBase = offsetMethod === OffsetMethod.POSITION\n ? this._getScrollTop() : 0\n\n this._offsets = []\n this._targets = []\n\n this._scrollHeight = this._getScrollHeight()\n\n const targets = [].slice.call(document.querySelectorAll(this._selector))\n\n targets\n .map((element) => {\n let target\n const targetSelector = Util.getSelectorFromElement(element)\n\n if (targetSelector) {\n target = document.querySelector(targetSelector)\n }\n\n if (target) {\n const targetBCR = target.getBoundingClientRect()\n if (targetBCR.width || targetBCR.height) {\n // TODO (fat): remove sketch reliance on jQuery position/offset\n return [\n $(target)[offsetMethod]().top + offsetBase,\n targetSelector\n ]\n }\n }\n return null\n })\n .filter((item) => item)\n .sort((a, b) => a[0] - b[0])\n .forEach((item) => {\n this._offsets.push(item[0])\n this._targets.push(item[1])\n })\n }\n\n dispose() {\n $.removeData(this._element, DATA_KEY)\n $(this._scrollElement).off(EVENT_KEY)\n\n this._element = null\n this._scrollElement = null\n this._config = null\n this._selector = null\n this._offsets = null\n this._targets = null\n this._activeTarget = null\n this._scrollHeight = null\n }\n\n // Private\n\n _getConfig(config) {\n config = {\n ...Default,\n ...typeof config === 'object' && config ? config : {}\n }\n\n if (typeof config.target !== 'string') {\n let id = $(config.target).attr('id')\n if (!id) {\n id = Util.getUID(NAME)\n $(config.target).attr('id', id)\n }\n config.target = `#${id}`\n }\n\n Util.typeCheckConfig(NAME, config, DefaultType)\n\n return config\n }\n\n _getScrollTop() {\n return this._scrollElement === window\n ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop\n }\n\n _getScrollHeight() {\n return this._scrollElement.scrollHeight || Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight\n )\n }\n\n _getOffsetHeight() {\n return this._scrollElement === window\n ? window.innerHeight : this._scrollElement.getBoundingClientRect().height\n }\n\n _process() {\n const scrollTop = this._getScrollTop() + this._config.offset\n const scrollHeight = this._getScrollHeight()\n const maxScroll = this._config.offset +\n scrollHeight -\n this._getOffsetHeight()\n\n if (this._scrollHeight !== scrollHeight) {\n this.refresh()\n }\n\n if (scrollTop >= maxScroll) {\n const target = this._targets[this._targets.length - 1]\n\n if (this._activeTarget !== target) {\n this._activate(target)\n }\n return\n }\n\n if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n this._activeTarget = null\n this._clear()\n return\n }\n\n const offsetLength = this._offsets.length\n for (let i = offsetLength; i--;) {\n const isActiveTarget = this._activeTarget !== this._targets[i] &&\n scrollTop >= this._offsets[i] &&\n (typeof this._offsets[i + 1] === 'undefined' ||\n scrollTop < this._offsets[i + 1])\n\n if (isActiveTarget) {\n this._activate(this._targets[i])\n }\n }\n }\n\n _activate(target) {\n this._activeTarget = target\n\n this._clear()\n\n let queries = this._selector.split(',')\n // eslint-disable-next-line arrow-body-style\n queries = queries.map((selector) => {\n return `${selector}[data-target=\"${target}\"],` +\n `${selector}[href=\"${target}\"]`\n })\n\n const $link = $([].slice.call(document.querySelectorAll(queries.join(','))))\n\n if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {\n $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)\n $link.addClass(ClassName.ACTIVE)\n } else {\n // Set triggered link as active\n $link.addClass(ClassName.ACTIVE)\n // Set triggered links parents as active\n // With both
{%- endif -%} {%- if include.hide_markup == null -%} {%- highlight html -%} - {{- include.content | replace: 'data-src="holder.js', 'src="...' -}} + {%- if include.content contains ' + {%- endcapture -%} + {{- img_placeholder -}} + {%- else -%} + {{- content_chunk -}} + {%- endif -%} + {%- endfor -%} + {%- else -%} + {{- include.content -}} + {%- endif -%} {%- endhighlight -%} {%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_includes/footer.html b/vendor/twbs/bootstrap/site/_includes/footer.html index 8e16577c1..03192a861 100644 --- a/vendor/twbs/bootstrap/site/_includes/footer.html +++ b/vendor/twbs/bootstrap/site/_includes/footer.html @@ -2,11 +2,11 @@
-

Designed and built with all the love in the world by @mdo and @fat. Maintained by the core team with the help of our contributors.

-

Currently v{{ site.current_version }}. Code licensed MIT, docs CC BY 3.0.

+

Designed and built with all the love in the world by the Bootstrap team with the help of our contributors.

+

Currently v{{ site.current_version }}. Code licensed MIT, docs CC BY 3.0.

diff --git a/vendor/twbs/bootstrap/site/_includes/header.html b/vendor/twbs/bootstrap/site/_includes/header.html index b92a5790a..8fa50f395 100644 --- a/vendor/twbs/bootstrap/site/_includes/header.html +++ b/vendor/twbs/bootstrap/site/_includes/header.html @@ -4,6 +4,9 @@ + + + {%- if page.title -%} {{ page.title | smartify }} · {{ site.title | smartify }} @@ -12,26 +15,9 @@ {%- endif -%} - -{% if site.github %} - -{% else %} - -{% endif %} - - -{% if page.layout == "docs" %} - -{% endif %} - + +{% include stylesheet.html %} {% include favicons.html %} - {% include social.html %} - - - +{% include analytics.html %} diff --git a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg new file mode 100644 index 000000000..079c881a0 --- /dev/null +++ b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap-stack.svg @@ -0,0 +1 @@ +Bootstrap \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg index 816028bd8..ec6da152f 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/bootstrap.svg @@ -1 +1 @@ -Bootstrap +Bootstrap \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/download.svg b/vendor/twbs/bootstrap/site/_includes/icons/download.svg index aa5f3f1be..ef8af7662 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/download.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/download.svg @@ -1 +1 @@ -Download icon + \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/github.svg b/vendor/twbs/bootstrap/site/_includes/icons/github.svg index 5d6ad1804..0243df5a2 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/github.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/github.svg @@ -1 +1 @@ -GitHub +GitHub \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/import.svg b/vendor/twbs/bootstrap/site/_includes/icons/import.svg index 0a9dbb269..28563c2be 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/import.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/import.svg @@ -1 +1 @@ -Import icon + \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/lightning.svg b/vendor/twbs/bootstrap/site/_includes/icons/lightning.svg index be6f475ef..bbcf24a76 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/lightning.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/lightning.svg @@ -1 +1 @@ -Lightning icon + \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/menu.svg b/vendor/twbs/bootstrap/site/_includes/icons/menu.svg index 03e15dc49..f6c47035a 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/menu.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/menu.svg @@ -1 +1 @@ -Menu +Menu \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg b/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg new file mode 100644 index 000000000..090d41dff --- /dev/null +++ b/vendor/twbs/bootstrap/site/_includes/icons/opencollective.svg @@ -0,0 +1 @@ +Open Collective \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg b/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg new file mode 100644 index 000000000..36883e82d --- /dev/null +++ b/vendor/twbs/bootstrap/site/_includes/icons/placeholder.svg @@ -0,0 +1,35 @@ +{%- comment -%} + Usage: include icons/placeholder.svg args + + args can be one of the following: + title: Used in the SVG `title` tag + text: The text to show in the image - default: 'width x height' + class: default: 'bd-placeholder-img' + color: The text color (foreground) - default: '#dee2e6' + background: The background color - default: '#868e96' + width: default: 100% + height: default: 180px +{%- endcomment -%} + +{%- assign title = include.title | default: 'Placeholder' -%} +{%- assign class = include.class | default: '' -%} +{%- assign color = include.color | default: site.data.grays[2].hex -%} +{%- assign background = include.background | default: site.data.grays[5].hex -%} +{%- assign width = include.width | default: '100%' -%} +{%- assign height = include.height | default: '180' -%} + +{%- if include.text -%} + {%- assign text = include.text -%} +{%- else -%} + {%- assign text = width | append: 'x' | append: height -%} +{%- endif -%} + +{%- capture svg -%} + + {% if title != ' ' %}{{ title }}{% endif %} + + {% if text != ' ' %}{{ text }}{% endif %} + +{%- endcapture -%} + +{{- svg | replace: ' ', '' | strip_newlines -}} diff --git a/vendor/twbs/bootstrap/site/_includes/icons/slack.svg b/vendor/twbs/bootstrap/site/_includes/icons/slack.svg index 3927fa458..d6ae455d8 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/slack.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/slack.svg @@ -1 +1 @@ -Slack +Slack \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg b/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg index 450c393b9..7b838be58 100644 --- a/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg +++ b/vendor/twbs/bootstrap/site/_includes/icons/twitter.svg @@ -1 +1 @@ -Twitter +Twitter \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/_includes/scripts.html b/vendor/twbs/bootstrap/site/_includes/scripts.html index 92c6d01cd..044dd3368 100644 --- a/vendor/twbs/bootstrap/site/_includes/scripts.html +++ b/vendor/twbs/bootstrap/site/_includes/scripts.html @@ -1,26 +1,23 @@ - + - - -{%- if site.github -%} - +{%- if jekyll.environment == "production" -%} + {%- else -%} - + {%- endif -%} {%- if page.layout == "docs" -%} {%- endif -%} -{%- if site.github -%} +{%- if jekyll.environment == "production" -%} {%- else -%} - + - {%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_includes/skippy.html b/vendor/twbs/bootstrap/site/_includes/skippy.html index 2c73089bc..ec7507d53 100644 --- a/vendor/twbs/bootstrap/site/_includes/skippy.html +++ b/vendor/twbs/bootstrap/site/_includes/skippy.html @@ -1,5 +1,3 @@ - -
- Skip to main content -
+
+ Skip to main content diff --git a/vendor/twbs/bootstrap/site/_includes/stylesheet.html b/vendor/twbs/bootstrap/site/_includes/stylesheet.html new file mode 100644 index 000000000..3846f9fe1 --- /dev/null +++ b/vendor/twbs/bootstrap/site/_includes/stylesheet.html @@ -0,0 +1,16 @@ + +{%- if jekyll.environment == "production" %} + +{% else %} + +{% endif -%} + +{%- if page.layout == "docs" or page.layout != "examples" -%} + +{% if page.layout == "docs" %} + +{% endif %} +{% if page.layout != "examples" %} + +{% endif %} +{%- endif -%} diff --git a/vendor/twbs/bootstrap/site/_layouts/default.html b/vendor/twbs/bootstrap/site/_layouts/default.html index 28f4cdccb..59f5c122b 100644 --- a/vendor/twbs/bootstrap/site/_layouts/default.html +++ b/vendor/twbs/bootstrap/site/_layouts/default.html @@ -8,7 +8,7 @@ {% include docs-navbar.html %} - {% if page.layout == "simple" or page.layout == "examples" %} + {% if page.layout == "simple" %} {{ content }} {% else %}
diff --git a/vendor/twbs/bootstrap/site/_layouts/examples.html b/vendor/twbs/bootstrap/site/_layouts/examples.html index 1f8fbcdec..cecd1145d 100644 --- a/vendor/twbs/bootstrap/site/_layouts/examples.html +++ b/vendor/twbs/bootstrap/site/_layouts/examples.html @@ -1,16 +1,55 @@ ---- -layout: default ---- + + + + + + + + + {{ page.title | smartify }} · {{ site.title | smartify }} -
-
-

{{ page.title | smartify }}

-

{{ page.description | smartify }}

- Download source code -
- {% include ads.html %} -
+ -
- {{ content }} -
+ {% include stylesheet.html %} + + + + {%- for css in page.extra_css %} + + + {%- endfor %} + + + {{ content }} + + {%- if page.include_js != false -%} + + + + {%- if jekyll.environment == "production" -%} + + {%- else -%} + + {%- endif -%} + + {%- for js in page.extra_js %} + + {%- endfor %} + {%- endif -%} + + diff --git a/vendor/twbs/bootstrap/site/_layouts/redirect.html b/vendor/twbs/bootstrap/site/_layouts/redirect.html deleted file mode 100644 index a30e77bf4..000000000 --- a/vendor/twbs/bootstrap/site/_layouts/redirect.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - Bootstrap · Content moved - - - - - - - -

Redirecting…

- Click here if you are not redirected - - diff --git a/vendor/twbs/bootstrap/site/_layouts/simple.html b/vendor/twbs/bootstrap/site/_layouts/simple.html index dfd9afd16..bbf808df3 100644 --- a/vendor/twbs/bootstrap/site/_layouts/simple.html +++ b/vendor/twbs/bootstrap/site/_layouts/simple.html @@ -2,11 +2,17 @@ layout: default --- -
-
-

{{ page.title | smartify }}

+
+
+

{{ page.title | smartify }}

{{ page.description | smartify }}

- {% include ads.html %} - {{ content }} -
-
+ {%- if page.title == "Examples" -%} + Download source code + {%- endif -%} + + {% include ads.html %} + + +
+ {{ content }} +
diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css b/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css deleted file mode 100644 index d83c39ff6..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * Bootstrap Docs (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. For - * details, see https://creativecommons.org/licenses/by/3.0/. - */.bd-navbar{min-height:4rem;background-color:#563d7c;box-shadow:0 .5rem 1rem rgba(0,0,0,.05),inset 0 -1px 0 rgba(0,0,0,.1)}@media (max-width:991.98px){.bd-navbar{padding-right:.5rem;padding-left:.5rem}.bd-navbar .navbar-nav-scroll{max-width:100%;height:2.5rem;margin-top:.25rem;overflow:hidden;font-size:.875rem}.bd-navbar .navbar-nav-scroll .navbar-nav{padding-bottom:2rem;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-navbar{position:-webkit-sticky;position:sticky;top:0;z-index:1071}}}.bd-navbar .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem;color:#cbbde2}.bd-navbar .navbar-nav .nav-link.active,.bd-navbar .navbar-nav .nav-link:hover{color:#fff;background-color:transparent}.bd-navbar .navbar-nav .nav-link.active{font-weight:500}.bd-navbar .navbar-nav-svg{display:inline-block;width:1rem;height:1rem;vertical-align:text-top}.bd-navbar .dropdown-menu{font-size:.875rem}.bd-navbar .dropdown-item.active{font-weight:500;color:#212529;background-color:transparent;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:.4rem .6rem;background-size:.75rem .75rem}.bd-masthead{position:relative;padding:3rem 15px}.bd-masthead h1{line-height:1}.bd-masthead .btn{width:100%;padding:.8rem 2rem;font-size:1.25rem;font-weight:500}.bd-masthead .carbonad{margin-top:0!important;margin-bottom:-3rem!important}@media (min-width:576px){.bd-masthead{padding-top:5rem;padding-bottom:5rem}.bd-masthead .carbonad{margin-bottom:0!important}}@media (min-width:768px){.bd-masthead h1{font-size:4rem}.bd-masthead .carbonad{margin-top:3rem!important}}.half-rule{width:6rem;margin:2.5rem 0}.masthead-followup .bd-clipboard{display:none}.masthead-followup .highlight{padding:.5rem 0;background-color:transparent}#carbonads{position:static;display:block;max-width:400px;padding:15px 15px 15px 160px;margin:2rem 0;overflow:hidden;font-size:13px;line-height:1.4;text-align:left;background-color:rgba(0,0,0,.05)}#carbonads a{color:#333;text-decoration:none}@media (min-width:576px){#carbonads{max-width:330px;border-radius:4px}}.carbon-img{float:left;margin-left:-145px}.carbon-poweredby{display:block;color:#777!important}.bd-content{-ms-flex-order:1;order:1}.bd-content>h2[id],.bd-content>h3[id],.bd-content>h4[id]{pointer-events:none}.bd-content>h2[id]>a,.bd-content>h2[id]>div,.bd-content>h3[id]>a,.bd-content>h3[id]>div,.bd-content>h4[id]>a,.bd-content>h4[id]>div{pointer-events:auto}.bd-content>h2[id]::before,.bd-content>h3[id]::before,.bd-content>h4[id]::before{display:block;height:6rem;margin-top:-6rem;visibility:hidden;content:""}.bd-content>table{width:100%;max-width:100%;margin-bottom:1rem}@media (max-width:991.98px){.bd-content>table{display:block;overflow-x:auto;-ms-overflow-style:-ms-autohiding-scrollbar}.bd-content>table.table-bordered{border:0}}.bd-content>table>tbody>tr>td,.bd-content>table>tbody>tr>th,.bd-content>table>tfoot>tr>td,.bd-content>table>tfoot>tr>th,.bd-content>table>thead>tr>td,.bd-content>table>thead>tr>th{padding:.75rem;vertical-align:top;border:1px solid #dee2e6}.bd-content>table>tbody>tr>td>p:last-child,.bd-content>table>tbody>tr>th>p:last-child,.bd-content>table>tfoot>tr>td>p:last-child,.bd-content>table>tfoot>tr>th>p:last-child,.bd-content>table>thead>tr>td>p:last-child,.bd-content>table>thead>tr>th>p:last-child{margin-bottom:0}.bd-content>table td:first-child>code{white-space:nowrap}.bd-content>h2:not(:first-child){margin-top:3rem}.bd-content>h3{margin-top:1.5rem}.bd-content>ol li,.bd-content>ul li{margin-bottom:.25rem}@media (min-width:992px){.bd-content>ol,.bd-content>p,.bd-content>ul{max-width:80%}}.bd-title{margin-top:1rem;margin-bottom:.5rem;font-weight:300}@media (min-width:576px){.bd-title{font-size:3rem}}.bd-lead{font-size:1.125rem;font-weight:300}@media (min-width:576px){.bd-lead{max-width:80%;margin-bottom:1rem;font-size:1.5rem}}.bd-text-purple{color:#563d7c}.bd-text-purple-bright{color:#7952b3}#skippy{display:block;padding:1em;color:#fff;background-color:#563d7c;outline:0}#skippy .skiplink-text{padding:.5em;outline:1px dotted}.bd-toc{-ms-flex-order:2;order:2;padding-top:1.5rem;padding-bottom:1.5rem;font-size:.875rem}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-toc{position:-webkit-sticky;position:sticky;top:4rem;height:calc(100vh - 4rem);overflow-y:auto}}.section-nav{padding-left:0;border-left:1px solid #eee}.section-nav ul{padding-left:1rem}.section-nav ul ul{display:none}.toc-entry{display:block}.toc-entry a{display:block;padding:.125rem 1.5rem;color:#99979c}.toc-entry a:hover{color:#007bff;text-decoration:none}.bd-sidebar{-ms-flex-order:0;order:0;border-bottom:1px solid rgba(0,0,0,.1)}@media (min-width:768px){.bd-sidebar{border-right:1px solid rgba(0,0,0,.1)}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-sidebar{position:-webkit-sticky;position:sticky;top:4rem;z-index:1000;height:calc(100vh - 4rem)}}}@media (min-width:1200px){.bd-sidebar{-ms-flex:0 1 320px;flex:0 1 320px}}.bd-links{padding-top:1rem;padding-bottom:1rem;margin-right:-15px;margin-left:-15px}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-links{max-height:calc(100vh - 9rem);overflow-y:auto}}}@media (min-width:768px){.bd-links{display:block!important}}.bd-search{position:relative;padding:1rem 15px;margin-right:-15px;margin-left:-15px;border-bottom:1px solid rgba(0,0,0,.05)}.bd-search .form-control:focus{border-color:#7952b3;box-shadow:0 0 0 3px rgba(121,82,179,.25)}.bd-search-docs-toggle{line-height:1;color:#212529}.bd-sidenav{display:none}.bd-toc-link{display:block;padding:.25rem 1.5rem;font-weight:500;color:rgba(0,0,0,.65)}.bd-toc-link:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-toc-item.active{margin-bottom:1rem}.bd-toc-item.active:not(:first-child){margin-top:1rem}.bd-toc-item.active>.bd-toc-link{color:rgba(0,0,0,.85)}.bd-toc-item.active>.bd-toc-link:hover{background-color:transparent}.bd-toc-item.active>.bd-sidenav{display:block}.bd-sidebar .nav>li>a{display:block;padding:.25rem 1.5rem;font-size:90%;color:rgba(0,0,0,.65)}.bd-sidebar .nav>li>a:hover{color:rgba(0,0,0,.85);text-decoration:none;background-color:transparent}.bd-sidebar .nav>.active:hover>a,.bd-sidebar .nav>.active>a{font-weight:500;color:rgba(0,0,0,.85);background-color:transparent}.bd-footer{font-size:85%;text-align:center;background-color:#f7f7f7}.bd-footer a{font-weight:500;color:#495057}.bd-footer a:focus,.bd-footer a:hover{color:#007bff}.bd-footer p{margin-bottom:0}@media (min-width:576px){.bd-footer{text-align:left}}.bd-footer-links{padding-left:0;margin-bottom:1rem}.bd-footer-links li{display:inline-block}.bd-footer-links li+li{margin-left:1rem}.bd-example-row .row>.col,.bd-example-row .row>[class^=col-]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.2)}.bd-example-row .row+.row{margin-top:1rem}.bd-example-row .flex-items-bottom,.bd-example-row .flex-items-middle,.bd-example-row .flex-items-top{min-height:6rem;background-color:rgba(255,0,0,.1)}.bd-example-row-flex-cols .row{min-height:10rem;background-color:rgba(255,0,0,.1)}.bd-highlight{background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.15)}.example-container{width:800px;width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.example-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.example-content-main{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-main{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-main{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}}.example-content-secondary{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-secondary{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-secondary{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}}.bd-example-container{min-width:16rem;max-width:25rem;margin-right:auto;margin-left:auto}.bd-example-container-header{height:3rem;margin-bottom:.5rem;background-color:#fff;border-radius:.25rem}.bd-example-container-sidebar{float:right;width:4rem;height:8rem;background-color:#80bdff;border-radius:.25rem}.bd-example-container-body{height:8rem;margin-right:4.5rem;background-color:#957bbe;border-radius:.25rem}.bd-example-container-fluid{max-width:none}.bd-example{position:relative;padding:1rem;margin:1rem -15px 0;border:solid #f8f9fa;border-width:.2rem 0 0}.bd-example::after{display:block;clear:both;content:""}@media (min-width:576px){.bd-example{padding:1.5rem;margin-right:0;margin-left:0;border-width:.2rem}}.bd-example+.clipboard+.highlight,.bd-example+.highlight{margin-top:0}.bd-example+p{margin-top:2rem}.bd-example .pos-f-t{position:relative;margin:-1rem}@media (min-width:576px){.bd-example .pos-f-t{margin:-1.5rem}}.bd-example .custom-file-input:lang(es)~.custom-file-label::after{content:"Elegir"}.bd-example>.form-control+.form-control{margin-top:.5rem}.bd-example>.alert+.alert,.bd-example>.nav+.nav,.bd-example>.navbar+.navbar,.bd-example>.progress+.btn,.bd-example>.progress+.progress{margin-top:1rem}.bd-example>.dropdown-menu:first-child{position:static;display:block}.bd-example>.form-group:last-child{margin-bottom:0}.bd-example>.close{float:none}.bd-example-type .table .type-info{color:#999;vertical-align:middle}.bd-example-type .table td{padding:1rem 0;border-color:#eee}.bd-example-type .table tr:first-child td{border-top:0}.bd-example-type h1,.bd-example-type h2,.bd-example-type h3,.bd-example-type h4,.bd-example-type h5,.bd-example-type h6{margin-top:0;margin-bottom:0}.bd-example-bg-classes p{padding:1rem}.bd-example>img+img{margin-left:.5rem}.bd-example>.btn-group{margin-top:.25rem;margin-bottom:.25rem}.bd-example>.btn-toolbar+.btn-toolbar{margin-top:.5rem}.bd-example-control-sizing input[type=text]+input[type=text],.bd-example-control-sizing select{margin-top:.5rem}.bd-example-form .input-group{margin-bottom:.5rem}.bd-example>textarea.form-control{resize:vertical}.bd-example>.list-group{max-width:400px}.bd-example .fixed-top,.bd-example .sticky-top{position:static;margin:-1rem -1rem 1rem}.bd-example .fixed-bottom{position:static;margin:1rem -1rem -1rem}@media (min-width:576px){.bd-example .fixed-top,.bd-example .sticky-top{margin:-1.5rem -1.5rem 1rem}.bd-example .fixed-bottom{margin:1rem -1.5rem -1.5rem}}.bd-example .pagination{margin-top:.5rem;margin-bottom:.5rem}.modal{z-index:1072}.modal .popover,.modal .tooltip{z-index:1073}.modal-backdrop{z-index:1071}.bd-example-modal{background-color:#fafafa}.bd-example-modal .modal{position:relative;top:auto;right:auto;bottom:auto;left:auto;z-index:1;display:block}.bd-example-modal .modal-dialog{left:auto;margin-right:auto;margin-left:auto}.bd-example-tabs .nav-tabs{margin-bottom:1rem}.bd-example-popover-static{padding-bottom:1.5rem;background-color:#f9f9f9}.bd-example-popover-static .popover{position:relative;display:block;float:left;width:260px;margin:1.25rem}.tooltip-demo a{white-space:nowrap}.bd-example-tooltip-static .tooltip{position:relative;display:inline-block;margin:10px 20px;opacity:1}.scrollspy-example{position:relative;height:200px;margin-top:.5rem;overflow:auto}.scrollspy-example-2{position:relative;height:350px;overflow:auto}.bd-example-border-utils [class^=border]{display:inline-block;width:5rem;height:5rem;margin:.25rem;background-color:#f5f5f5}.bd-example-border-utils-0 [class^=border]{border:1px solid #dee2e6}.highlight{padding:1rem;margin-top:1rem;margin-bottom:1rem;background-color:#f8f9fa;-ms-overflow-style:-ms-autohiding-scrollbar}@media (min-width:576px){.highlight{padding:1.5rem}}.bd-content .highlight{margin-right:-15px;margin-left:-15px}@media (min-width:576px){.bd-content .highlight{margin-right:0;margin-left:0}}.highlight pre{padding:0;margin-top:0;margin-bottom:0;background-color:transparent;border:0}.highlight pre code{font-size:inherit;color:#212529}.btn-bd-primary{font-weight:500;color:#7952b3;border-color:#7952b3}.btn-bd-primary:active,.btn-bd-primary:hover{color:#fff;background-color:#7952b3;border-color:#7952b3}.btn-bd-primary:focus{box-shadow:0 0 0 3px rgba(121,82,179,.25)}.btn-bd-download{font-weight:500;color:#ffe484;border-color:#ffe484}.btn-bd-download:active,.btn-bd-download:hover{color:#2a2730;background-color:#ffe484;border-color:#ffe484}.btn-bd-download:focus{box-shadow:0 0 0 3px rgba(255,228,132,.25)}.bd-callout{padding:1.25rem;margin-top:1.25rem;margin-bottom:1.25rem;border:1px solid #eee;border-left-width:.25rem;border-radius:.25rem}.bd-callout h4{margin-top:0;margin-bottom:.25rem}.bd-callout p:last-child{margin-bottom:0}.bd-callout code{border-radius:.25rem}.bd-callout+.bd-callout{margin-top:-.25rem}.bd-callout-info{border-left-color:#5bc0de}.bd-callout-info h4{color:#5bc0de}.bd-callout-warning{border-left-color:#f0ad4e}.bd-callout-warning h4{color:#f0ad4e}.bd-callout-danger{border-left-color:#d9534f}.bd-callout-danger h4{color:#d9534f}.bd-examples .img-thumbnail{margin-bottom:.75rem}.bd-examples h4{margin-bottom:.25rem}.bd-examples p{margin-bottom:1.25rem}@media (max-width:480px){.bd-examples{margin-right:-.75rem;margin-left:-.75rem}.bd-examples>[class^=col-]{padding-right:.75rem;padding-left:.75rem}}.bd-browser-bugs td p{margin-bottom:0}.bd-browser-bugs th:first-child{width:18%}.bd-brand-logos{display:table;width:100%;margin-bottom:1rem;overflow:hidden;color:#563d7c;background-color:#f9f9f9;border-radius:.25rem}.bd-brand-item{padding:4rem 0;text-align:center}.bd-brand-item+.bd-brand-item{border-top:1px solid #fff}.bd-brand-logos .inverse{color:#fff;background-color:#563d7c}.bd-brand-item h1,.bd-brand-item h3{margin-top:0;margin-bottom:0}.bd-brand-item .bd-booticon{margin-right:auto;margin-left:auto}@media (min-width:768px){.bd-brand-item{display:table-cell;width:1%}.bd-brand-item+.bd-brand-item{border-top:0;border-left:1px solid #fff}.bd-brand-item h1{font-size:4rem}}.color-swatches{margin:0 -5px;overflow:hidden}.color-swatch{float:left;width:4rem;height:4rem;margin-right:.25rem;margin-left:.25rem;border-radius:.25rem}@media (min-width:768px){.color-swatch{width:6rem;height:6rem}}.color-swatches .bd-purple{background-color:#563d7c}.color-swatches .bd-purple-light{background-color:#cbbde2}.color-swatches .bd-purple-lighter{background-color:#e5e1ea}.color-swatches .bd-gray{background-color:#f9f9f9}.swatch-blue{color:#fff;background-color:#007bff}.swatch-indigo{color:#fff;background-color:#6610f2}.swatch-purple{color:#fff;background-color:#6f42c1}.swatch-pink{color:#fff;background-color:#e83e8c}.swatch-red{color:#fff;background-color:#dc3545}.swatch-orange{color:#212529;background-color:#fd7e14}.swatch-yellow{color:#212529;background-color:#ffc107}.swatch-green{color:#fff;background-color:#28a745}.swatch-teal{color:#fff;background-color:#20c997}.swatch-cyan{color:#fff;background-color:#17a2b8}.swatch-white{color:#212529;background-color:#fff}.swatch-gray{color:#fff;background-color:#6c757d}.swatch-gray-dark{color:#fff;background-color:#343a40}.swatch-primary{color:#fff;background-color:#007bff}.swatch-secondary{color:#fff;background-color:#6c757d}.swatch-success{color:#fff;background-color:#28a745}.swatch-info{color:#fff;background-color:#17a2b8}.swatch-warning{color:#212529;background-color:#ffc107}.swatch-danger{color:#fff;background-color:#dc3545}.swatch-light{color:#212529;background-color:#f8f9fa}.swatch-dark{color:#fff;background-color:#343a40}.swatch-100{color:#212529;background-color:#f8f9fa}.swatch-200{color:#212529;background-color:#e9ecef}.swatch-300{color:#212529;background-color:#dee2e6}.swatch-400{color:#212529;background-color:#ced4da}.swatch-500{color:#212529;background-color:#adb5bd}.swatch-600{color:#fff;background-color:#6c757d}.swatch-700{color:#fff;background-color:#495057}.swatch-800{color:#fff;background-color:#343a40}.swatch-900{color:#fff;background-color:#212529}.bd-clipboard{position:relative;display:none;float:right}.bd-clipboard+.highlight{margin-top:0}.btn-clipboard{position:absolute;top:.5rem;right:.5rem;z-index:10;display:block;padding:.25rem .5rem;font-size:75%;color:#818a91;cursor:pointer;background-color:transparent;border:0;border-radius:.25rem}.btn-clipboard:hover{color:#fff;background-color:#027de7}@media (min-width:768px){.bd-clipboard{display:block}}.hll{background-color:#ffc}.c{color:#999}.k{color:#069}.o{color:#555}.cm{color:#999}.cp{color:#099}.c1{color:#999}.cs{color:#999}.gd{background-color:#fcc;border:1px solid #c00}.ge{font-style:italic}.gr{color:red}.gh{color:#030}.gi{background-color:#cfc;border:1px solid #0c0}.go{color:#aaa}.gp{color:#009}.gu{color:#030}.gt{color:#9c6}.kc{color:#069}.kd{color:#069}.kn{color:#069}.kp{color:#069}.kr{color:#069}.kt{color:#078}.m{color:#f60}.s{color:#d44950}.na{color:#4f9fcf}.nb{color:#366}.nc{color:#0a8}.no{color:#360}.nd{color:#99f}.ni{color:#999}.ne{color:#c00}.nf{color:#c0f}.nl{color:#99f}.nn{color:#0cf}.nt{color:#2f6f9f}.nv{color:#033}.ow{color:#000}.w{color:#bbb}.mf{color:#f60}.mh{color:#f60}.mi{color:#f60}.mo{color:#f60}.sb{color:#c30}.sc{color:#c30}.sd{font-style:italic;color:#c30}.s2{color:#c30}.se{color:#c30}.sh{color:#c30}.si{color:#a00}.sx{color:#c30}.sr{color:#3aa}.s1{color:#c30}.ss{color:#fc3}.bp{color:#366}.vc{color:#033}.vg{color:#033}.vi{color:#033}.il{color:#f60}.css .nt+.nt,.css .o,.css .o+.nt{color:#999}.language-bash::before,.language-sh::before{color:#009;content:"$ ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.language-powershell::before{color:#009;content:"PM> ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.anchorjs-link{font-weight:400;color:rgba(0,123,255,.5);transition:color .16s linear}.anchorjs-link:hover{color:#007bff;text-decoration:none}.algolia-autocomplete{display:block!important;-ms-flex:1;flex:1}.algolia-autocomplete .ds-dropdown-menu{width:100%;min-width:0!important;max-width:none!important;padding:.75rem 0!important;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.175)}@media (min-width:768px){.algolia-autocomplete .ds-dropdown-menu{width:175%}}.algolia-autocomplete .ds-dropdown-menu::before{display:none!important}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{padding:0!important;overflow:visible!important;background-color:transparent!important;border:0!important}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion{padding:0!important;overflow:visible!important}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{padding:.125rem 1rem!important;margin-top:0!important;font-size:.875rem!important;font-weight:500!important;color:#7952b3!important;border-bottom:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{float:none!important;padding-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:none!important;width:auto!important;padding:0!important;text-align:left!important}.algolia-autocomplete .algolia-docsearch-suggestion--content{float:none!important;width:auto!important;padding:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--content::before{display:none!important}.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header{padding-top:.75rem!important;margin-top:.75rem!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column{display:none!important}.algolia-autocomplete .algolia-docsearch-suggestion--title{display:block;padding:.25rem 1rem!important;margin-bottom:0!important;font-size:.875rem!important;font-weight:400!important}.algolia-autocomplete .algolia-docsearch-suggestion--text{padding:0 1rem .5rem!important;margin-top:-.25rem;font-size:.875rem!important;font-weight:400;line-height:1.25!important}.algolia-autocomplete .algolia-docsearch-footer{float:none!important;width:auto!important;height:auto!important;padding:.75rem 1rem 0;font-size:.75rem!important;line-height:1!important;color:#767676!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .algolia-docsearch-footer--logo{display:inline!important;overflow:visible!important;color:inherit!important;text-indent:0!important;background:0 0!important}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#5f2dab;background-color:rgba(154,132,187,.12)}.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{box-shadow:inset 0 -2px 0 0 rgba(95,45,171,.5)!important}.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content{background-color:rgba(208,189,236,.15)!important} -/*# sourceMappingURL=docs.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css.map b/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css.map deleted file mode 100644 index ff148d83d..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/css/docs.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["../scss/docs.scss","../scss/_nav.scss","../../../../../scss/mixins/_breakpoints.scss","../scss/_masthead.scss","../scss/_ads.scss","../scss/_content.scss","site/docs/4.1/assets/css/docs.min.css","../scss/_skiplink.scss","../scss/_sidebar.scss","../scss/_footer.scss","../scss/_component-examples.scss","../../../../../scss/mixins/_grid.scss","../../../../../scss/mixins/_clearfix.scss","../scss/_buttons.scss","../scss/_callouts.scss","../scss/_examples.scss","../scss/_browser-bugs.scss","../scss/_brand.scss","../scss/_colors.scss","../scss/_clipboard-js.scss","../scss/_syntax.scss","../scss/_anchor.scss","../scss/_algolia.scss"],"names":[],"mappings":"AAAA;;;;;;ACIA,WACE,WAAA,KACA,iBAAA,QACA,WAAA,EAAA,MAAA,KAAA,eAAA,CAAA,MAAA,EAAA,KAAA,EAAA,eCkEE,4BDrEJ,WAMI,cAAA,MACA,aAAA,MAPJ,8BAUM,UAAA,KACA,OAAA,OACA,WAAA,OACA,SAAA,OACA,UAAA,QAdN,0CAiBQ,eAAA,KACA,WAAA,KACA,YAAA,OACA,2BAAA,OCoCJ,yBD9B4B,2DA1BhC,WA2BM,SAAA,eAAA,SAAA,OACA,IAAA,EACA,QAAA,OA7BN,iCAmCM,cAAA,MACA,aAAA,MACA,MAAA,QArCN,wCAAA,uCAyCQ,MAAA,KACA,iBAAA,YA1CR,wCA8CQ,YAAA,IA9CR,2BAoDI,QAAA,aACA,MAAA,KACA,OAAA,KACA,eAAA,SAvDJ,0BA2DI,UAAA,QA3DJ,iCA+DI,YAAA,IACA,MAAA,QACA,iBAAA,YACA,iBAAA,wPACA,kBAAA,UACA,oBAAA,MAAA,MACA,gBAAA,OAAA,OEvEJ,aACE,SAAA,SACA,QAAA,KAAA,KAFF,gBAMI,YAAA,EANJ,kBAUI,MAAA,KACA,QAAA,MAAA,KACA,UAAA,QACA,YAAA,IAbJ,uBAiBI,WAAA,YACA,cAAA,gBDwCA,yBC1DJ,aAsBI,YAAA,KACA,eAAA,KAvBJ,uBA0BM,cAAA,aDgCF,yBC1DJ,gBAgCM,UAAA,KAhCN,uBAoCM,WAAA,gBAKN,WACE,MAAA,KACA,OAAA,OAAA,EAGF,iCACkB,QAAA,KADlB,8BAII,QAAA,MAAA,EACA,iBAAA,YC/CJ,WACE,SAAA,OACA,QAAA,MACA,UAAA,MACA,QAAA,KAAA,KAAA,KAAA,MACA,OAAA,KAAA,EACA,SAAA,OACA,UAAA,KACA,YAAA,IACA,WAAA,KACA,iBAAA,gBAVF,aAaI,MAAA,KACA,gBAAA,KFwCA,yBEtDJ,WAkBI,UAAA,MACA,cAAA,KAIJ,YACE,MAAA,KACA,YAAA,OAGF,kBACE,QAAA,MACA,MAAA,eC9BF,YACE,eAAA,EAAA,MAAA,EADF,mBCyKA,mBACA,mBDnKI,eAAA,KCwKJ,qBD/KA,uBCiLA,qBADA,uBAGA,qBADA,uBDvKM,eAAA,KAXN,2BCwLA,2BACA,2BD1KM,QAAA,MACA,OAAA,KACA,WAAA,MACA,WAAA,OACA,QAAA,GAnBN,kBAwBI,MAAA,KACA,UAAA,KACA,cAAA,KHyCA,4BGnEJ,kBA6BM,QAAA,MACA,WAAA,KACA,mBAAA,yBA/BN,iCAkCQ,OAAA,GCmLR,8BADA,8BAGA,8BADA,8BAHA,8BDnNA,8BA6CU,QAAA,OACA,eAAA,IACA,OAAA,IAAA,MAAA,QCiLV,2CADA,2CAGA,2CADA,2CAHA,2CD9NA,2CAkDY,cAAA,EAlDZ,sCA0DM,YAAA,OASN,iCAEI,WAAA,KAFJ,eAMI,WAAA,OC0KJ,kBDhLA,kBAWI,cAAA,OHxBA,yBImMF,eACA,cDvLF,eAkBM,UAAA,KAKN,UACE,WAAA,KACA,cAAA,MACA,YAAA,IHvCE,yBGoCJ,UAMI,UAAA,MAIJ,SACE,UAAA,SACA,YAAA,IHhDE,yBG8CJ,SAKI,UAAA,IACA,cAAA,KACA,UAAA,QAIJ,gBAAkB,MAAA,QAClB,uBAAyB,MAAA,QEpHzB,QACE,QAAA,MACA,QAAA,IACA,MAAA,KACA,iBAAA,QACA,QAAA,EALF,uBAQI,QAAA,KACA,QAAA,IAAA,OCLJ,QAOE,eAAA,EAAA,MAAA,EACA,YAAA,OACA,eAAA,OACA,UAAA,QAT4B,2DAD9B,QAEI,SAAA,eAAA,SAAA,OACA,IAAA,KACA,OAAA,mBACA,WAAA,MAQJ,aACE,aAAA,EACA,YAAA,IAAA,MAAA,KAFF,gBAKI,aAAA,KALJ,mBAQM,QAAA,KAKN,WACE,QAAA,MADF,aAII,QAAA,MACA,QAAA,QAAA,OACA,MAAA,QANJ,mBASM,MAAA,QACA,gBAAA,KASN,YACE,eAAA,EAAA,MAAA,EAEA,cAAA,IAAA,MAAA,eNME,yBMTJ,YAYI,aAAA,IAAA,MAAA,eAN4B,2DANhC,YAOM,SAAA,eAAA,SAAA,OACA,IAAA,KACA,QAAA,KACA,OAAA,qBNDF,0BMTJ,YAgBI,SAAA,EAAA,EAAA,MAAA,KAAA,EAAA,EAAA,OAIJ,UACE,YAAA,KACA,eAAA,KACA,aAAA,MACA,YAAA,MNfE,yBMkB4B,2DAPhC,UAQM,WAAA,mBACA,WAAA,ONpBF,yBMWJ,UAeI,QAAA,iBAIJ,WACE,SAAA,SACA,QAAA,KAAA,KACA,aAAA,MACA,YAAA,MACA,cAAA,IAAA,MAAA,gBALF,+BAQI,aAAA,QACA,WAAA,EAAA,EAAA,EAAA,IAAA,qBAIJ,uBACE,YAAA,EACA,MAAA,QAGF,YACE,QAAA,KAGF,aACE,QAAA,MACA,QAAA,OAAA,OACA,YAAA,IACA,MAAA,gBAJF,mBAOI,MAAA,gBACA,gBAAA,KAIJ,oBAEI,cAAA,KAFJ,sCAKM,WAAA,KALN,iCASM,MAAA,gBATN,uCAYQ,iBAAA,YAZR,gCAiBM,QAAA,MAMN,sBACE,QAAA,MACA,QAAA,OAAA,OACA,UAAA,IACA,MAAA,gBAGF,4BACE,MAAA,gBACA,gBAAA,KACA,iBAAA,YF0TF,iCEvTA,2BAEE,YAAA,IACA,MAAA,gBACA,iBAAA,YChKF,WACE,UAAA,IACA,WAAA,OACA,iBAAA,QAHF,aAMI,YAAA,IACA,MAAA,QAPJ,mBAAA,mBAWM,MAAA,QAXN,aAgBI,cAAA,EPwCA,yBOxDJ,WAoBI,WAAA,MAIJ,iBACE,aAAA,EACA,cAAA,KAFF,oBAKI,QAAA,aALJ,uBAQM,YAAA,KC9BN,0BJ8fA,mCI1fM,YAAA,OACA,eAAA,OACA,iBAAA,oBACA,OAAA,IAAA,MAAA,mBAPN,0BAYI,WAAA,KJ+fJ,mCADA,mCI1gBA,gCAkBI,WAAA,KACA,iBAAA,iBAIJ,+BACE,WAAA,MACA,iBAAA,iBAGF,cACE,iBAAA,oBACA,OAAA,IAAA,MAAA,oBAIF,mBACE,MAAA,MCpCA,MAAA,KACA,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KDoCF,aCtBE,QAAA,YAAA,QAAA,KACA,cAAA,KAAA,UAAA,KACA,aAAA,MACA,YAAA,MDuBF,sBCnBE,SAAA,SAIA,MAAA,KACA,WAAA,IACA,cAAA,KACA,aAAA,KTuBE,yBQXJ,sBCRE,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,KTeE,yBQXJ,sBCRE,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,YDgBF,2BC/BE,SAAA,SAIA,MAAA,KACA,WAAA,IACA,cAAA,KACA,aAAA,KTuBE,yBQCJ,2BCpBE,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,KTeE,yBQCJ,2BCpBE,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,YDiCF,sBACE,UAAA,MACA,UAAA,MACA,aAAA,KACA,YAAA,KAGF,6BACE,OAAA,KACA,cAAA,MACA,iBAAA,KACA,cAAA,OAGF,8BACE,MAAA,MACA,MAAA,KACA,OAAA,KACA,iBAAA,QACA,cAAA,OAGF,2BACE,OAAA,KACA,aAAA,OACA,iBAAA,QACA,cAAA,OAGF,4BACE,UAAA,KAQF,YACE,SAAA,SACA,QAAA,KACA,OAAA,KAAA,MAAA,EACA,OAAA,MAAA,QACA,aAAA,MAAA,EAAA,EExHA,mBACE,QAAA,MACA,MAAA,KACA,QAAA,GVwDA,yBQwDJ,YASI,QAAA,OACA,aAAA,EACA,YAAA,EACA,aAAA,OJ2hBJ,kCIviBA,uBAiBI,WAAA,EAjBJ,cAqBI,WAAA,KArBJ,qBAyBI,SAAA,SACA,OAAA,MRlFA,yBQwDJ,qBA6BM,OAAA,SA7BN,kEAkCI,QAAA,SAlCJ,wCAuCM,WAAA,MJ4hBN,0BInkBA,sBJokBA,4BAEA,2BADA,gCIrhBI,WAAA,KAhDJ,uCAoDI,SAAA,OACA,QAAA,MArDJ,mCAyDI,cAAA,EAzDJ,mBA6DI,MAAA,KAKJ,mCAGM,MAAA,KACA,eAAA,OAJN,2BAOM,QAAA,KAAA,EACA,aAAA,KARN,0CAWM,WAAA,EAXN,oBJoiBA,oBACA,oBACA,oBACA,oBACA,oBInhBI,WAAA,EACA,cAAA,EAKJ,yBACE,QAAA,KAIF,oBAEI,YAAA,MAKJ,uBAEI,WAAA,OACA,cAAA,OAHJ,sCAMI,WAAA,MJkhBJ,6DI7gBA,kCAEE,WAAA,MAEF,8BACE,cAAA,MAEF,kCACE,OAAA,SAIF,wBACE,UAAA,MAIF,uBJ6gBA,wBI1gBI,SAAA,OACA,OAAA,MAAA,MAAA,KAJJ,0BAOI,SAAA,OACA,OAAA,KAAA,MAAA,MRrMA,yBQ6LJ,uBJyhBE,wBI3gBI,OAAA,QAAA,QAAA,KAdN,0BAiBM,OAAA,KAAA,QAAA,SAMN,wBACE,WAAA,MACA,cAAA,MAIF,OACE,QAAA,KJ6gBF,gBI9gBA,gBAKI,QAAA,KAIJ,gBACE,QAAA,KAGF,kBACE,iBAAA,QADF,yBAII,SAAA,SACA,IAAA,KACA,MAAA,KACA,OAAA,KACA,KAAA,KACA,QAAA,EACA,QAAA,MAVJ,gCAcI,KAAA,KACA,aAAA,KACA,YAAA,KAKJ,2BACE,cAAA,KAIF,2BACE,eAAA,OACA,iBAAA,QAFF,oCAKI,SAAA,SACA,QAAA,MACA,MAAA,KACA,MAAA,MACA,OAAA,QAKJ,gBACE,YAAA,OAGF,oCACE,SAAA,SACA,QAAA,aACA,OAAA,KAAA,KACA,QAAA,EAIF,mBACE,SAAA,SACA,OAAA,MACA,WAAA,MACA,SAAA,KAGF,qBACE,SAAA,SACA,OAAA,MACA,SAAA,KAGF,yCAEI,QAAA,aACA,MAAA,KACA,OAAA,KACA,OAAA,OACA,iBAAA,QAIJ,2CAEI,OAAA,IAAA,MAAA,QAQJ,WACE,QAAA,KACA,WAAA,KACA,cAAA,KACA,iBAAA,QACA,mBAAA,yBRjUE,yBQ4TJ,WAQI,QAAA,QAIJ,uBACE,aAAA,MACA,YAAA,MR1UE,yBQwUJ,uBAKI,aAAA,EACA,YAAA,GAIJ,eAEI,QAAA,EACA,WAAA,EACA,cAAA,EACA,iBAAA,YACA,OAAA,EANJ,oBASI,UAAA,QACA,MAAA,QGpZJ,gBACE,YAAA,IACA,MAAA,QACA,aAAA,QAHF,uBAAA,sBAOI,MAAA,KACA,iBAAA,QACA,aAAA,QATJ,sBAaI,WAAA,EAAA,EAAA,EAAA,IAAA,qBAIJ,iBACE,YAAA,IACA,MAAA,QACA,aAAA,QAHF,wBAAA,uBAOI,MAAA,QACA,iBAAA,QACA,aAAA,QATJ,uBAaI,WAAA,EAAA,EAAA,EAAA,IAAA,sBC9BJ,YACE,QAAA,QACA,WAAA,QACA,cAAA,QACA,OAAA,IAAA,MAAA,KACA,kBAAA,OACA,cAAA,OAGF,eACE,WAAA,EACA,cAAA,OAGF,yBACE,cAAA,EAGF,iBACE,cAAA,OAGF,wBACE,WAAA,QAUF,iBALE,kBAAA,QAEA,oBAAK,MAAA,QAIP,oBANE,kBAAA,QAEA,uBAAK,MAAA,QAKP,mBAPE,kBAAA,QAEA,sBAAK,MAAA,QC9BP,4BACE,cAAA,OAEF,gBACE,cAAA,OAEF,eACE,cAAA,QAGF,yBACE,aACE,aAAA,QACA,YAAA,QAEF,2BACE,cAAA,OACA,aAAA,QCjBJ,sBAEI,cAAA,EAFJ,gCAKI,MAAA,ICFJ,gBACE,QAAA,MACA,MAAA,KACA,cAAA,KACA,SAAA,OACA,MAAA,QACA,iBAAA,QACA,cAAA,OAIF,eACE,QAAA,KAAA,EACA,WAAA,OAEF,8BACE,WAAA,IAAA,MAAA,KAEF,yBACE,MAAA,KACA,iBAAA,QAIF,kBXugCA,kBWrgCE,WAAA,EACA,cAAA,EAEF,4BACE,aAAA,KACA,YAAA,KAmBF,yBACE,eACE,QAAA,WACA,MAAA,GAEF,8BACE,WAAA,EACA,YAAA,IAAA,MAAA,KAEF,kBACE,UAAA,MASJ,gBACE,OAAA,EAAA,KACA,SAAA,OAGF,cACE,MAAA,KACA,MAAA,KACA,OAAA,KACA,aAAA,OACA,YAAA,OACA,cAAA,OAEA,yBARF,cASI,MAAA,KACA,OAAA,MAKJ,2BAEI,iBAAA,QAFJ,iCAKI,iBAAA,QALJ,mCAQI,iBAAA,QARJ,yBAWI,iBAAA,QCtGF,aACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,QACA,iBAAA,QAFF,eACE,MAAA,QACA,iBAAA,QAFF,cACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,cACE,MAAA,QACA,iBAAA,KAFF,aACE,MAAA,KACA,iBAAA,QAFF,kBACE,MAAA,KACA,iBAAA,QAKF,gBACE,MAAA,KACA,iBAAA,QAFF,kBACE,MAAA,KACA,iBAAA,QAFF,gBACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,gBACE,MAAA,QACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,cACE,MAAA,QACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAKF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QCjBJ,cACE,SAAA,SACA,QAAA,KACA,MAAA,MAHF,yBAMI,WAAA,EAIJ,eACE,SAAA,SACA,IAAA,MACA,MAAA,MACA,QAAA,GACA,QAAA,MACA,QAAA,OAAA,MACA,UAAA,IACA,MAAA,QACA,OAAA,QACA,iBAAA,YACA,OAAA,EACA,cAAA,OAZF,qBAeI,MAAA,KACA,iBAAA,QAIJ,yBACE,cACE,QAAA,OClCJ,KAAO,iBAAA,KACP,GAAK,MAAA,KACL,GAAK,MAAA,KACL,GAAK,MAAA,KACL,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,iBAAA,KAAwB,OAAA,IAAA,MAAA,KAC9B,IAAM,WAAA,OACN,IAAM,MAAA,IACN,IAAM,MAAA,KACN,IAAM,iBAAA,KAAwB,OAAA,IAAA,MAAA,KAC9B,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,GAAK,MAAA,KACL,GAAK,MAAA,QACL,IAAM,MAAA,QACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,QACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,GAAK,MAAA,KACL,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,WAAA,OAAoB,MAAA,KAC1B,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,Kdk9CN,ach9CA,Qd+8CA,Yc78CiB,MAAA,KAEjB,uBdi9CA,qBc/8CE,MAAA,KACA,QAAA,KACA,oBAAA,KAAA,iBAAA,KAAA,gBAAA,KAAA,YAAA,KAGF,6BACE,MAAA,KACA,QAAA,OACA,oBAAA,KAAA,iBAAA,KAAA,gBAAA,KAAA,YAAA,KC5EF,eACE,YAAA,IACA,MAAA,mBACA,WAAA,MAAA,KAAA,OAHF,qBAMI,MAAA,QACA,gBAAA,KCFJ,sBACE,QAAA,gBACA,SAAA,EAAA,KAAA,EAFF,wCAMI,MAAA,KACA,UAAA,YACA,UAAA,eACA,QAAA,OAAA,YACA,iBAAA,KACA,gBAAA,YACA,OAAA,IAAA,MAAA,eACA,WAAA,EAAA,MAAA,KAAA,iBpB0CA,yBoBvDJ,wCAgBM,MAAA,MAhBN,gDAqBM,QAAA,eArBN,6DAyBM,QAAA,YACA,SAAA,kBACA,iBAAA,sBACA,OAAA,YA5BN,wDAgCM,WAAA,YAhCN,oDAqCI,QAAA,YACA,SAAA,kBAtCJ,qEA0CI,QAAA,QAAA,eACA,WAAA,YACA,UAAA,kBACA,YAAA,cACA,MAAA,kBACA,cAAA,YA/CJ,6DAmDI,MAAA,eACA,YAAA,YApDJ,wEAyDI,MAAA,eACA,MAAA,eACA,QAAA,YACA,WAAA,eA5DJ,6DAgEI,MAAA,eACA,MAAA,eACA,QAAA,YAlEJ,qEAsEM,QAAA,eAtEN,sGA6EQ,YAAA,iBACA,WAAA,iBACA,WAAA,IAAA,MAAA,eA/ER,uFAoFM,QAAA,eApFN,2DAyFI,QAAA,MACA,QAAA,OAAA,eACA,cAAA,YACA,UAAA,kBACA,YAAA,cA7FJ,0DAiGI,QAAA,EAAA,KAAA,gBACA,WAAA,QACA,UAAA,kBACA,YAAA,IACA,YAAA,eArGJ,gDAyGI,MAAA,eACA,MAAA,eACA,OAAA,eACA,QAAA,OAAA,KAAA,EACA,UAAA,iBACA,YAAA,YACA,MAAA,kBACA,WAAA,IAAA,MAAA,eAhHJ,sDAoHI,QAAA,iBACA,SAAA,kBACA,MAAA,kBACA,YAAA,YACA,WAAA,cAxHJ,+DA4HI,MAAA,QACA,iBAAA,sBA7HJ,mGAiII,WAAA,MAAA,EAAA,KAAA,EAAA,EAAA,6BAjIJ,sFAqII,iBAAA","sourcesContent":["/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License. For\n * details, see https://creativecommons.org/licenses/by/3.0/.\n */\n\n// Dev notes\n//\n// Background information on nomenclature and architecture decisions here.\n//\n// - Bootstrap functions, variables, and mixins are included for easy reuse.\n// Doing so gives us access to the same core utilities provided by Bootstrap.\n// For example, consistent media queries through those mixins.\n//\n// - Bootstrap's **docs variables** are prefixed with `$bd-`.\n// These custom colors avoid collision with the components Bootstrap provides.\n//\n// - Classes are prefixed with `.bd-`.\n// These classes indicate custom-built or modified components for the design\n// and layout of the Bootstrap docs. They are not included in our builds.\n//\n// Happy Bootstrapping!\n\n// Load Bootstrap variables and mixins\n@import \"../../../../../scss/functions\";\n@import \"../../../../../scss/variables\";\n@import \"../../../../../scss/mixins\";\n\n// Load docs components\n@import \"variables\";\n@import \"nav\";\n@import \"masthead\";\n@import \"ads\";\n@import \"content\";\n@import \"skiplink\";\n@import \"sidebar\";\n@import \"footer\";\n@import \"component-examples\";\n@import \"buttons\";\n@import \"callouts\";\n@import \"examples\";\n@import \"browser-bugs\";\n@import \"brand\";\n@import \"colors\";\n@import \"clipboard-js\";\n\n// Load docs dependencies\n@import \"syntax\";\n@import \"anchor\";\n@import \"algolia\";\n","//\n// Main navbar\n//\n\n.bd-navbar {\n min-height: 4rem;\n background-color: $bd-purple;\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .1);\n\n @include media-breakpoint-down(md) {\n padding-right: .5rem;\n padding-left: .5rem;\n\n .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n font-size: .875rem;\n\n .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n }\n }\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: 1071; // over everything in bootstrap\n }\n }\n\n .navbar-nav {\n .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: $bd-purple-light;\n\n &.active,\n &:hover {\n color: #fff;\n background-color: transparent;\n }\n\n &.active {\n font-weight: 500;\n }\n }\n }\n\n .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n }\n\n .dropdown-menu {\n font-size: .875rem;\n }\n\n .dropdown-item.active {\n font-weight: 500;\n color: $gray-900;\n background-color: transparent;\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: .4rem .6rem;\n background-size: .75rem .75rem;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n.bd-masthead {\n position: relative;\n padding: 3rem ($grid-gutter-width / 2);\n // background-image: linear-gradient(45deg, #fafafa, #f5f5f5);\n\n h1 {\n line-height: 1;\n }\n\n .btn {\n width: 100%;\n padding: .8rem 2rem;\n font-size: 1.25rem;\n font-weight: 500;\n }\n\n .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n }\n\n @include media-breakpoint-up(sm) {\n padding-top: 5rem;\n padding-bottom: 5rem;\n\n .carbonad {\n margin-bottom: 0 !important;\n }\n }\n\n @include media-breakpoint-up(md) {\n h1 {\n font-size: 4rem;\n }\n\n .carbonad {\n margin-top: 3rem !important;\n }\n }\n}\n\n.half-rule {\n width: 6rem;\n margin: 2.5rem 0;\n}\n\n.masthead-followup {\n .bd-clipboard { display: none; }\n\n .highlight {\n padding: .5rem 0;\n background-color: transparent;\n }\n}\n","// stylelint-disable declaration-no-important, selector-max-id\n\n//\n// Carbon ads\n//\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n font-size: 13px;\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, .05);\n\n a {\n color: #333;\n text-decoration: none;\n }\n\n @include media-breakpoint-up(sm) {\n max-width: 330px;\n border-radius: 4px;\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n color: #777 !important;\n}\n","// stylelint-disable no-duplicate-selectors, selector-max-combinators, selector-max-compound-selectors, selector-max-type, selector-no-qualifying-type\n\n//\n// Automatically style Markdown-based tables like a Bootstrap `.table`.\n//\n\n.bd-content {\n order: 1;\n\n // Hack the sticky header\n > h2[id],\n > h3[id],\n > h4[id] {\n pointer-events: none;\n\n > div,\n > a {\n pointer-events: auto;\n }\n\n &::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n visibility: hidden;\n content: \"\";\n }\n }\n\n > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n\n @include media-breakpoint-down(md) {\n display: block;\n overflow-x: auto;\n -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057\n\n &.table-bordered {\n border: 0;\n }\n }\n\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: $table-cell-padding;\n vertical-align: top;\n border: 1px solid $table-border-color;\n\n > p:last-child {\n margin-bottom: 0;\n }\n }\n }\n }\n\n // Prevent breaking of code (e.g., Grunt tasks list)\n td:first-child > code {\n white-space: nowrap;\n }\n }\n}\n\n//\n// Docs sections\n//\n\n.bd-content {\n > h2:not(:first-child) {\n margin-top: 3rem;\n }\n\n > h3 {\n margin-top: 1.5rem;\n }\n\n > ul li,\n > ol li {\n margin-bottom: .25rem;\n }\n\n @include media-breakpoint-up(lg) {\n > ul,\n > ol,\n > p {\n max-width: 80%;\n }\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n font-weight: 300;\n\n @include media-breakpoint-up(sm) {\n font-size: 3rem;\n }\n}\n\n.bd-lead {\n font-size: 1.125rem;\n font-weight: 300;\n\n @include media-breakpoint-up(sm) {\n max-width: 80%;\n margin-bottom: 1rem;\n font-size: 1.5rem;\n }\n}\n\n.bd-text-purple { color: $bd-purple; }\n.bd-text-purple-bright { color: $bd-purple-bright; }\n","/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License. For\n * details, see https://creativecommons.org/licenses/by/3.0/.\n */\n.bd-navbar {\n min-height: 4rem;\n background-color: #563d7c;\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.05), inset 0 -1px 0 rgba(0, 0, 0, 0.1);\n}\n\n@media (max-width: 991.98px) {\n .bd-navbar {\n padding-right: .5rem;\n padding-left: .5rem;\n }\n .bd-navbar .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n font-size: .875rem;\n }\n .bd-navbar .navbar-nav-scroll .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-navbar {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1071;\n }\n }\n}\n\n.bd-navbar .navbar-nav .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: #cbbde2;\n}\n\n.bd-navbar .navbar-nav .nav-link.active, .bd-navbar .navbar-nav .nav-link:hover {\n color: #fff;\n background-color: transparent;\n}\n\n.bd-navbar .navbar-nav .nav-link.active {\n font-weight: 500;\n}\n\n.bd-navbar .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n}\n\n.bd-navbar .dropdown-menu {\n font-size: .875rem;\n}\n\n.bd-navbar .dropdown-item.active {\n font-weight: 500;\n color: #212529;\n background-color: transparent;\n background-image: url(\"data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: .4rem .6rem;\n background-size: .75rem .75rem;\n}\n\n.bd-masthead {\n position: relative;\n padding: 3rem 15px;\n}\n\n.bd-masthead h1 {\n line-height: 1;\n}\n\n.bd-masthead .btn {\n width: 100%;\n padding: .8rem 2rem;\n font-size: 1.25rem;\n font-weight: 500;\n}\n\n.bd-masthead .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n}\n\n@media (min-width: 576px) {\n .bd-masthead {\n padding-top: 5rem;\n padding-bottom: 5rem;\n }\n .bd-masthead .carbonad {\n margin-bottom: 0 !important;\n }\n}\n\n@media (min-width: 768px) {\n .bd-masthead h1 {\n font-size: 4rem;\n }\n .bd-masthead .carbonad {\n margin-top: 3rem !important;\n }\n}\n\n.half-rule {\n width: 6rem;\n margin: 2.5rem 0;\n}\n\n.masthead-followup .bd-clipboard {\n display: none;\n}\n\n.masthead-followup .highlight {\n padding: .5rem 0;\n background-color: transparent;\n}\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n font-size: 13px;\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n#carbonads a {\n color: #333;\n text-decoration: none;\n}\n\n@media (min-width: 576px) {\n #carbonads {\n max-width: 330px;\n border-radius: 4px;\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n color: #777 !important;\n}\n\n.bd-content {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.bd-content > h2[id],\n.bd-content > h3[id],\n.bd-content > h4[id] {\n pointer-events: none;\n}\n\n.bd-content > h2[id] > div,\n.bd-content > h2[id] > a,\n.bd-content > h3[id] > div,\n.bd-content > h3[id] > a,\n.bd-content > h4[id] > div,\n.bd-content > h4[id] > a {\n pointer-events: auto;\n}\n\n.bd-content > h2[id]::before,\n.bd-content > h3[id]::before,\n.bd-content > h4[id]::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n visibility: hidden;\n content: \"\";\n}\n\n.bd-content > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n}\n\n@media (max-width: 991.98px) {\n .bd-content > table {\n display: block;\n overflow-x: auto;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n }\n .bd-content > table.table-bordered {\n border: 0;\n }\n}\n\n.bd-content > table > thead > tr > th,\n.bd-content > table > thead > tr > td,\n.bd-content > table > tbody > tr > th,\n.bd-content > table > tbody > tr > td,\n.bd-content > table > tfoot > tr > th,\n.bd-content > table > tfoot > tr > td {\n padding: 0.75rem;\n vertical-align: top;\n border: 1px solid #dee2e6;\n}\n\n.bd-content > table > thead > tr > th > p:last-child,\n.bd-content > table > thead > tr > td > p:last-child,\n.bd-content > table > tbody > tr > th > p:last-child,\n.bd-content > table > tbody > tr > td > p:last-child,\n.bd-content > table > tfoot > tr > th > p:last-child,\n.bd-content > table > tfoot > tr > td > p:last-child {\n margin-bottom: 0;\n}\n\n.bd-content > table td:first-child > code {\n white-space: nowrap;\n}\n\n.bd-content > h2:not(:first-child) {\n margin-top: 3rem;\n}\n\n.bd-content > h3 {\n margin-top: 1.5rem;\n}\n\n.bd-content > ul li,\n.bd-content > ol li {\n margin-bottom: .25rem;\n}\n\n@media (min-width: 992px) {\n .bd-content > ul,\n .bd-content > ol,\n .bd-content > p {\n max-width: 80%;\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n font-weight: 300;\n}\n\n@media (min-width: 576px) {\n .bd-title {\n font-size: 3rem;\n }\n}\n\n.bd-lead {\n font-size: 1.125rem;\n font-weight: 300;\n}\n\n@media (min-width: 576px) {\n .bd-lead {\n max-width: 80%;\n margin-bottom: 1rem;\n font-size: 1.5rem;\n }\n}\n\n.bd-text-purple {\n color: #563d7c;\n}\n\n.bd-text-purple-bright {\n color: #7952b3;\n}\n\n#skippy {\n display: block;\n padding: 1em;\n color: #fff;\n background-color: #563d7c;\n outline: 0;\n}\n\n#skippy .skiplink-text {\n padding: .5em;\n outline: 1px dotted;\n}\n\n.bd-toc {\n -ms-flex-order: 2;\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n font-size: .875rem;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-toc {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n height: calc(100vh - 4rem);\n overflow-y: auto;\n }\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n}\n\n.section-nav ul {\n padding-left: 1rem;\n}\n\n.section-nav ul ul {\n display: none;\n}\n\n.toc-entry {\n display: block;\n}\n\n.toc-entry a {\n display: block;\n padding: .125rem 1.5rem;\n color: #99979c;\n}\n\n.toc-entry a:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.bd-sidebar {\n -ms-flex-order: 0;\n order: 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n@media (min-width: 768px) {\n .bd-sidebar {\n border-right: 1px solid rgba(0, 0, 0, 0.1);\n }\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-sidebar {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: calc(100vh - 4rem);\n }\n }\n}\n\n@media (min-width: 1200px) {\n .bd-sidebar {\n -ms-flex: 0 1 320px;\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-links {\n max-height: calc(100vh - 9rem);\n overflow-y: auto;\n }\n }\n}\n\n@media (min-width: 768px) {\n .bd-links {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative;\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.bd-search .form-control:focus {\n border-color: #7952b3;\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.bd-search-docs-toggle {\n line-height: 1;\n color: #212529;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-toc-link:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n}\n\n.bd-toc-item.active {\n margin-bottom: 1rem;\n}\n\n.bd-toc-item.active:not(:first-child) {\n margin-top: 1rem;\n}\n\n.bd-toc-item.active > .bd-toc-link {\n color: rgba(0, 0, 0, 0.85);\n}\n\n.bd-toc-item.active > .bd-toc-link:hover {\n background-color: transparent;\n}\n\n.bd-toc-item.active > .bd-sidenav {\n display: block;\n}\n\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n font-size: 90%;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 500;\n color: rgba(0, 0, 0, 0.85);\n background-color: transparent;\n}\n\n.bd-footer {\n font-size: 85%;\n text-align: center;\n background-color: #f7f7f7;\n}\n\n.bd-footer a {\n font-weight: 500;\n color: #495057;\n}\n\n.bd-footer a:hover, .bd-footer a:focus {\n color: #007bff;\n}\n\n.bd-footer p {\n margin-bottom: 0;\n}\n\n@media (min-width: 576px) {\n .bd-footer {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n}\n\n.bd-footer-links li {\n display: inline-block;\n}\n\n.bd-footer-links li + li {\n margin-left: 1rem;\n}\n\n.bd-example-row .row > .col,\n.bd-example-row .row > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.2);\n}\n\n.bd-example-row .row + .row {\n margin-top: 1rem;\n}\n\n.bd-example-row .flex-items-top,\n.bd-example-row .flex-items-middle,\n.bd-example-row .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-highlight {\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.15);\n}\n\n.example-container {\n width: 800px;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.example-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.example-content-main {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-main {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-main {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n}\n\n.example-content-secondary {\n position: relative;\n width: 100%;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-secondary {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-secondary {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n}\n\n.bd-example-container {\n min-width: 16rem;\n max-width: 25rem;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-container-header {\n height: 3rem;\n margin-bottom: .5rem;\n background-color: white;\n border-radius: .25rem;\n}\n\n.bd-example-container-sidebar {\n float: right;\n width: 4rem;\n height: 8rem;\n background-color: #80bdff;\n border-radius: .25rem;\n}\n\n.bd-example-container-body {\n height: 8rem;\n margin-right: 4.5rem;\n background-color: #957bbe;\n border-radius: .25rem;\n}\n\n.bd-example-container-fluid {\n max-width: none;\n}\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem -15px 0;\n border: solid #f8f9fa;\n border-width: .2rem 0 0;\n}\n\n.bd-example::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n@media (min-width: 576px) {\n .bd-example {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n}\n\n.bd-example + .highlight,\n.bd-example + .clipboard + .highlight {\n margin-top: 0;\n}\n\n.bd-example + p {\n margin-top: 2rem;\n}\n\n.bd-example .pos-f-t {\n position: relative;\n margin: -1rem;\n}\n\n@media (min-width: 576px) {\n .bd-example .pos-f-t {\n margin: -1.5rem;\n }\n}\n\n.bd-example .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n}\n\n.bd-example > .form-control + .form-control {\n margin-top: .5rem;\n}\n\n.bd-example > .nav + .nav,\n.bd-example > .alert + .alert,\n.bd-example > .navbar + .navbar,\n.bd-example > .progress + .progress,\n.bd-example > .progress + .btn {\n margin-top: 1rem;\n}\n\n.bd-example > .dropdown-menu:first-child {\n position: static;\n display: block;\n}\n\n.bd-example > .form-group:last-child {\n margin-bottom: 0;\n}\n\n.bd-example > .close {\n float: none;\n}\n\n.bd-example-type .table .type-info {\n color: #999;\n vertical-align: middle;\n}\n\n.bd-example-type .table td {\n padding: 1rem 0;\n border-color: #eee;\n}\n\n.bd-example-type .table tr:first-child td {\n border-top: 0;\n}\n\n.bd-example-type h1,\n.bd-example-type h2,\n.bd-example-type h3,\n.bd-example-type h4,\n.bd-example-type h5,\n.bd-example-type h6 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n.bd-example > img + img {\n margin-left: .5rem;\n}\n\n.bd-example > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n}\n\n.bd-example > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n}\n\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n.bd-example > .list-group {\n max-width: 400px;\n}\n\n.bd-example .fixed-top,\n.bd-example .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n}\n\n.bd-example .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n}\n\n@media (min-width: 576px) {\n .bd-example .fixed-top,\n .bd-example .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .bd-example .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n}\n\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n.modal {\n z-index: 1072;\n}\n\n.modal .tooltip,\n.modal .popover {\n z-index: 1073;\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n}\n\n.bd-example-modal .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n}\n\n.bd-example-modal .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n}\n\n.bd-example-popover-static .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n}\n\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n}\n\n.bd-example-border-utils-0 [class^=\"border\"] {\n border: 1px solid #dee2e6;\n}\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: #f8f9fa;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n@media (min-width: 576px) {\n .highlight {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 576px) {\n .bd-content .highlight {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight pre {\n padding: 0;\n margin-top: 0;\n margin-bottom: 0;\n background-color: transparent;\n border: 0;\n}\n\n.highlight pre code {\n font-size: inherit;\n color: #212529;\n}\n\n.btn-bd-primary {\n font-weight: 500;\n color: #7952b3;\n border-color: #7952b3;\n}\n\n.btn-bd-primary:hover, .btn-bd-primary:active {\n color: #fff;\n background-color: #7952b3;\n border-color: #7952b3;\n}\n\n.btn-bd-primary:focus {\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.btn-bd-download {\n font-weight: 500;\n color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:hover, .btn-bd-download:active {\n color: #2a2730;\n background-color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:focus {\n box-shadow: 0 0 0 3px rgba(255, 228, 132, 0.25);\n}\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n border-radius: .25rem;\n}\n\n.bd-callout h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n}\n\n.bd-callout p:last-child {\n margin-bottom: 0;\n}\n\n.bd-callout code {\n border-radius: .25rem;\n}\n\n.bd-callout + .bd-callout {\n margin-top: -.25rem;\n}\n\n.bd-callout-info {\n border-left-color: #5bc0de;\n}\n\n.bd-callout-info h4 {\n color: #5bc0de;\n}\n\n.bd-callout-warning {\n border-left-color: #f0ad4e;\n}\n\n.bd-callout-warning h4 {\n color: #f0ad4e;\n}\n\n.bd-callout-danger {\n border-left-color: #d9534f;\n}\n\n.bd-callout-danger h4 {\n color: #d9534f;\n}\n\n.bd-examples .img-thumbnail {\n margin-bottom: .75rem;\n}\n\n.bd-examples h4 {\n margin-bottom: .25rem;\n}\n\n.bd-examples p {\n margin-bottom: 1.25rem;\n}\n\n@media (max-width: 480px) {\n .bd-examples {\n margin-right: -.75rem;\n margin-left: -.75rem;\n }\n .bd-examples > [class^=\"col-\"] {\n padding-right: .75rem;\n padding-left: .75rem;\n }\n}\n\n.bd-browser-bugs td p {\n margin-bottom: 0;\n}\n\n.bd-browser-bugs th:first-child {\n width: 18%;\n}\n\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: #563d7c;\n background-color: #f9f9f9;\n border-radius: .25rem;\n}\n\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n}\n\n.bd-brand-item + .bd-brand-item {\n border-top: 1px solid #fff;\n}\n\n.bd-brand-logos .inverse {\n color: #fff;\n background-color: #563d7c;\n}\n\n.bd-brand-item h1,\n.bd-brand-item h3 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.bd-brand-item .bd-booticon {\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 768px) {\n .bd-brand-item {\n display: table-cell;\n width: 1%;\n }\n .bd-brand-item + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid #fff;\n }\n .bd-brand-item h1 {\n font-size: 4rem;\n }\n}\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden;\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n border-radius: .25rem;\n}\n\n@media (min-width: 768px) {\n .color-swatch {\n width: 6rem;\n height: 6rem;\n }\n}\n\n.color-swatches .bd-purple {\n background-color: #563d7c;\n}\n\n.color-swatches .bd-purple-light {\n background-color: #cbbde2;\n}\n\n.color-swatches .bd-purple-lighter {\n background-color: #e5e1ea;\n}\n\n.color-swatches .bd-gray {\n background-color: #f9f9f9;\n}\n\n.swatch-blue {\n color: #fff;\n background-color: #007bff;\n}\n\n.swatch-indigo {\n color: #fff;\n background-color: #6610f2;\n}\n\n.swatch-purple {\n color: #fff;\n background-color: #6f42c1;\n}\n\n.swatch-pink {\n color: #fff;\n background-color: #e83e8c;\n}\n\n.swatch-red {\n color: #fff;\n background-color: #dc3545;\n}\n\n.swatch-orange {\n color: #212529;\n background-color: #fd7e14;\n}\n\n.swatch-yellow {\n color: #212529;\n background-color: #ffc107;\n}\n\n.swatch-green {\n color: #fff;\n background-color: #28a745;\n}\n\n.swatch-teal {\n color: #fff;\n background-color: #20c997;\n}\n\n.swatch-cyan {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.swatch-white {\n color: #212529;\n background-color: #fff;\n}\n\n.swatch-gray {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-gray-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.swatch-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.swatch-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.swatch-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.swatch-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.swatch-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.swatch-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-100 {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.swatch-200 {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.swatch-300 {\n color: #212529;\n background-color: #dee2e6;\n}\n\n.swatch-400 {\n color: #212529;\n background-color: #ced4da;\n}\n\n.swatch-500 {\n color: #212529;\n background-color: #adb5bd;\n}\n\n.swatch-600 {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-700 {\n color: #fff;\n background-color: #495057;\n}\n\n.swatch-800 {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-900 {\n color: #fff;\n background-color: #212529;\n}\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n}\n\n.bd-clipboard + .highlight {\n margin-top: 0;\n}\n\n.btn-clipboard {\n position: absolute;\n top: .5rem;\n right: .5rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n font-size: 75%;\n color: #818a91;\n cursor: pointer;\n background-color: transparent;\n border: 0;\n border-radius: .25rem;\n}\n\n.btn-clipboard:hover {\n color: #fff;\n background-color: #027de7;\n}\n\n@media (min-width: 768px) {\n .bd-clipboard {\n display: block;\n }\n}\n\n.hll {\n background-color: #ffc;\n}\n\n.c {\n color: #999;\n}\n\n.k {\n color: #069;\n}\n\n.o {\n color: #555;\n}\n\n.cm {\n color: #999;\n}\n\n.cp {\n color: #099;\n}\n\n.c1 {\n color: #999;\n}\n\n.cs {\n color: #999;\n}\n\n.gd {\n background-color: #fcc;\n border: 1px solid #c00;\n}\n\n.ge {\n font-style: italic;\n}\n\n.gr {\n color: #f00;\n}\n\n.gh {\n color: #030;\n}\n\n.gi {\n background-color: #cfc;\n border: 1px solid #0c0;\n}\n\n.go {\n color: #aaa;\n}\n\n.gp {\n color: #009;\n}\n\n.gu {\n color: #030;\n}\n\n.gt {\n color: #9c6;\n}\n\n.kc {\n color: #069;\n}\n\n.kd {\n color: #069;\n}\n\n.kn {\n color: #069;\n}\n\n.kp {\n color: #069;\n}\n\n.kr {\n color: #069;\n}\n\n.kt {\n color: #078;\n}\n\n.m {\n color: #f60;\n}\n\n.s {\n color: #d44950;\n}\n\n.na {\n color: #4f9fcf;\n}\n\n.nb {\n color: #366;\n}\n\n.nc {\n color: #0a8;\n}\n\n.no {\n color: #360;\n}\n\n.nd {\n color: #99f;\n}\n\n.ni {\n color: #999;\n}\n\n.ne {\n color: #c00;\n}\n\n.nf {\n color: #c0f;\n}\n\n.nl {\n color: #99f;\n}\n\n.nn {\n color: #0cf;\n}\n\n.nt {\n color: #2f6f9f;\n}\n\n.nv {\n color: #033;\n}\n\n.ow {\n color: #000;\n}\n\n.w {\n color: #bbb;\n}\n\n.mf {\n color: #f60;\n}\n\n.mh {\n color: #f60;\n}\n\n.mi {\n color: #f60;\n}\n\n.mo {\n color: #f60;\n}\n\n.sb {\n color: #c30;\n}\n\n.sc {\n color: #c30;\n}\n\n.sd {\n font-style: italic;\n color: #c30;\n}\n\n.s2 {\n color: #c30;\n}\n\n.se {\n color: #c30;\n}\n\n.sh {\n color: #c30;\n}\n\n.si {\n color: #a00;\n}\n\n.sx {\n color: #c30;\n}\n\n.sr {\n color: #3aa;\n}\n\n.s1 {\n color: #c30;\n}\n\n.ss {\n color: #fc3;\n}\n\n.bp {\n color: #366;\n}\n\n.vc {\n color: #033;\n}\n\n.vg {\n color: #033;\n}\n\n.vi {\n color: #033;\n}\n\n.il {\n color: #f60;\n}\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt {\n color: #999;\n}\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.anchorjs-link {\n font-weight: 400;\n color: rgba(0, 123, 255, 0.5);\n transition: color .16s linear;\n}\n\n.anchorjs-link:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.algolia-autocomplete {\n display: block !important;\n -ms-flex: 1;\n flex: 1;\n}\n\n.algolia-autocomplete .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175);\n}\n\n@media (min-width: 768px) {\n .algolia-autocomplete .ds-dropdown-menu {\n width: 175%;\n }\n}\n\n.algolia-autocomplete .ds-dropdown-menu::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu .ds-suggestions {\n margin-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n font-size: .875rem !important;\n font-weight: 500 !important;\n color: #7952b3 !important;\n border-bottom: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--title {\n display: block;\n padding: .25rem 1rem !important;\n margin-bottom: 0 !important;\n font-size: .875rem !important;\n font-weight: 400 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text {\n padding: 0 1rem .5rem !important;\n margin-top: -.25rem;\n font-size: .875rem !important;\n font-weight: 400;\n line-height: 1.25 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n font-size: .75rem !important;\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, 0.12);\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, 0.5) !important;\n}\n\n.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, 0.15) !important;\n}\n/*# sourceMappingURL=docs.min.css.map */","// stylelint-disable selector-max-id\n\n#skippy {\n display: block;\n padding: 1em;\n color: #fff;\n background-color: $bd-purple;\n outline: 0;\n\n .skiplink-text {\n padding: .5em;\n outline: 1px dotted;\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Right side table of contents\n//\n\n.bd-toc {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n height: calc(100vh - 4rem);\n overflow-y: auto;\n }\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n font-size: .875rem;\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n\n ul {\n padding-left: 1rem;\n\n ul {\n display: none;\n }\n }\n}\n\n.toc-entry {\n display: block;\n\n a {\n display: block;\n padding: .125rem 1.5rem;\n color: #99979c;\n\n &:hover {\n color: $blue;\n text-decoration: none;\n }\n }\n}\n\n//\n// Left side navigation\n//\n\n.bd-sidebar {\n order: 0;\n // background-color: #f5f2f9;\n border-bottom: 1px solid rgba(0, 0, 0, .1);\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: calc(100vh - 4rem);\n }\n border-right: 1px solid rgba(0, 0, 0, .1);\n }\n\n @include media-breakpoint-up(xl) {\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n max-height: calc(100vh - 9rem);\n overflow-y: auto;\n }\n }\n\n // Override collapse behaviors\n @include media-breakpoint-up(md) {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative; // To contain the Algolia search\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, .05);\n\n .form-control:focus {\n border-color: $bd-purple-bright;\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.bd-search-docs-toggle {\n line-height: 1;\n color: $gray-900;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 500;\n color: rgba(0, 0, 0, .65);\n\n &:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n }\n}\n\n.bd-toc-item {\n &.active {\n margin-bottom: 1rem;\n\n &:not(:first-child) {\n margin-top: 1rem;\n }\n\n > .bd-toc-link {\n color: rgba(0, 0, 0, .85);\n\n &:hover {\n background-color: transparent;\n }\n }\n\n > .bd-sidenav {\n display: block;\n }\n }\n}\n\n// All levels of nav\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n font-size: 90%;\n color: rgba(0, 0, 0, .65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 500;\n color: rgba(0, 0, 0, .85);\n background-color: transparent;\n}\n","//\n// Footer\n//\n\n.bd-footer {\n font-size: 85%;\n text-align: center;\n background-color: #f7f7f7;\n\n a {\n font-weight: 500;\n color: $gray-700;\n\n &:hover,\n &:focus {\n color: $link-color;\n }\n }\n\n p {\n margin-bottom: 0;\n }\n\n @include media-breakpoint-up(sm) {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n\n li {\n display: inline-block;\n\n + li {\n margin-left: 1rem;\n }\n }\n}\n","// stylelint-disable no-duplicate-selectors, selector-no-qualifying-type\n\n//\n// Grid examples\n//\n\n.bd-example-row {\n .row {\n > .col,\n > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, .15);\n border: 1px solid rgba(86, 61, 124, .2);\n }\n }\n\n .row + .row {\n margin-top: 1rem;\n }\n\n .flex-items-top,\n .flex-items-middle,\n .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, .1);\n }\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, .1);\n}\n\n.bd-highlight {\n background-color: rgba($bd-purple, .15);\n border: 1px solid rgba($bd-purple, .15);\n}\n\n// Grid mixins\n.example-container {\n width: 800px;\n @include make-container();\n}\n\n.example-row {\n @include make-row();\n}\n\n.example-content-main {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(8);\n }\n}\n\n.example-content-secondary {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(4);\n }\n}\n\n\n//\n// Container illustrations\n//\n\n.bd-example-container {\n min-width: 16rem;\n max-width: 25rem;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-container-header {\n height: 3rem;\n margin-bottom: .5rem;\n background-color: lighten($blue, 50%);\n border-radius: .25rem;\n}\n\n.bd-example-container-sidebar {\n float: right;\n width: 4rem;\n height: 8rem;\n background-color: lighten($blue, 25%);\n border-radius: .25rem;\n}\n\n.bd-example-container-body {\n height: 8rem;\n margin-right: 4.5rem;\n background-color: lighten($bd-purple, 25%);\n border-radius: .25rem;\n}\n\n.bd-example-container-fluid {\n max-width: none;\n}\n\n\n//\n// Docs examples\n//\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem (-$grid-gutter-width / 2) 0;\n border: solid $gray-100;\n border-width: .2rem 0 0;\n @include clearfix();\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n\n + .highlight,\n + .clipboard + .highlight {\n margin-top: 0;\n }\n\n + p {\n margin-top: 2rem;\n }\n\n .pos-f-t {\n position: relative;\n margin: -1rem;\n\n @include media-breakpoint-up(sm) {\n margin: -1.5rem;\n }\n }\n\n .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n }\n\n > .form-control {\n + .form-control {\n margin-top: .5rem;\n }\n }\n\n > .nav + .nav,\n > .alert + .alert,\n > .navbar + .navbar,\n > .progress + .progress,\n > .progress + .btn {\n margin-top: 1rem;\n }\n\n > .dropdown-menu:first-child {\n position: static;\n display: block;\n }\n\n > .form-group:last-child {\n margin-bottom: 0;\n }\n\n > .close {\n float: none;\n }\n}\n\n// Typography\n.bd-example-type {\n .table {\n .type-info {\n color: #999;\n vertical-align: middle;\n }\n td {\n padding: 1rem 0;\n border-color: #eee;\n }\n tr:first-child td {\n border-top: 0;\n }\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 0;\n margin-bottom: 0;\n }\n}\n\n// Contextual background colors\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n// Images\n.bd-example > img {\n + img {\n margin-left: .5rem;\n }\n}\n\n// Buttons\n.bd-example {\n > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n }\n > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n }\n}\n\n// Forms\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n// List groups\n.bd-example > .list-group {\n max-width: 400px;\n}\n\n// Navbars\n.bd-example {\n .fixed-top,\n .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n }\n .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n }\n\n @include media-breakpoint-up(sm) {\n .fixed-top,\n .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n }\n}\n\n// Pagination\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n// Example modals\n.modal {\n z-index: 1072;\n\n .tooltip,\n .popover {\n z-index: 1073;\n }\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n\n .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n }\n\n .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n }\n}\n\n// Example tabbable tabs\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n// Popovers\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n\n .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n }\n}\n\n// Tooltips\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n// Scrollspy demo on fixed height div\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils {\n [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n }\n}\n\n.bd-example-border-utils-0 {\n [class^=\"border\"] {\n border: 1px solid $border-color;\n }\n}\n\n//\n// Code snippets\n//\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: $gray-100;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: (-$grid-gutter-width / 2);\n margin-left: (-$grid-gutter-width / 2);\n\n @include media-breakpoint-up(sm) {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight {\n pre {\n padding: 0;\n margin-top: 0;\n margin-bottom: 0;\n background-color: transparent;\n border: 0;\n }\n pre code {\n font-size: inherit;\n color: $gray-900; // Effectively the base text color\n }\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container() {\n width: 100%;\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row() {\n display: flex;\n flex-wrap: wrap;\n margin-right: ($grid-gutter-width / -2);\n margin-left: ($grid-gutter-width / -2);\n}\n\n@mixin make-col-ready() {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n min-height: 1px; // Prevent collapsing\n padding-right: ($grid-gutter-width / 2);\n padding-left: ($grid-gutter-width / 2);\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","// Buttons\n//\n// Custom buttons for the docs.\n\n.btn-bd-primary {\n font-weight: 500;\n color: $bd-purple-bright;\n border-color: $bd-purple-bright;\n\n &:hover,\n &:active {\n color: #fff;\n background-color: $bd-purple-bright;\n border-color: $bd-purple-bright;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.btn-bd-download {\n font-weight: 500;\n color: $bd-download;\n border-color: $bd-download;\n\n &:hover,\n &:active {\n color: $bd-dark;\n background-color: $bd-download;\n border-color: $bd-download;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-download, .25);\n }\n}\n","//\n// Callouts\n//\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n border-radius: .25rem;\n}\n\n.bd-callout h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n}\n\n.bd-callout p:last-child {\n margin-bottom: 0;\n}\n\n.bd-callout code {\n border-radius: .25rem;\n}\n\n.bd-callout + .bd-callout {\n margin-top: -.25rem;\n}\n\n// Variations\n@mixin bs-callout-variant($color) {\n border-left-color: $color;\n\n h4 { color: $color; }\n}\n\n.bd-callout-info { @include bs-callout-variant($bd-info); }\n.bd-callout-warning { @include bs-callout-variant($bd-warning); }\n.bd-callout-danger { @include bs-callout-variant($bd-danger); }\n","//\n// Examples\n//\n\n.bd-examples .img-thumbnail {\n margin-bottom: .75rem;\n}\n.bd-examples h4 {\n margin-bottom: .25rem;\n}\n.bd-examples p {\n margin-bottom: 1.25rem;\n}\n\n@media (max-width: 480px) {\n .bd-examples {\n margin-right: -.75rem;\n margin-left: -.75rem;\n }\n .bd-examples > [class^=\"col-\"] {\n padding-right: .75rem;\n padding-left: .75rem;\n }\n}\n","// Wall of Browser Bugs\n//\n// Better display for the responsive table on the Wall of Browser Bugs.\n\n.bd-browser-bugs {\n td p {\n margin-bottom: 0;\n }\n th:first-child {\n width: 18%;\n }\n}\n","// stylelint-disable no-duplicate-selectors\n\n//\n// Brand guidelines\n//\n\n// Logo series wrapper\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: #563d7c;\n background-color: #f9f9f9;\n border-radius: .25rem;\n}\n\n// Individual items\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n}\n.bd-brand-item + .bd-brand-item {\n border-top: 1px solid #fff;\n}\n.bd-brand-logos .inverse {\n color: #fff;\n background-color: #563d7c;\n}\n\n// Heading content within\n.bd-brand-item h1,\n.bd-brand-item h3 {\n margin-top: 0;\n margin-bottom: 0;\n}\n.bd-brand-item .bd-booticon {\n margin-right: auto;\n margin-left: auto;\n}\n\n// Make the icons stand out on what is/isn't okay\n// .bd-brand-item .glyphicon {\n// width: 30px;\n// height: 30px;\n// margin: 10px auto -10px;\n// line-height: 30px;\n// color: #fff;\n// border-radius: 50%;\n// }\n// .bd-brand-item .glyphicon-ok {\n// background-color: #5cb85c;\n// }\n// .bd-brand-item .glyphicon-remove {\n// background-color: #d9534f;\n// }\n\n@media (min-width: 768px) {\n .bd-brand-item {\n display: table-cell;\n width: 1%;\n }\n .bd-brand-item + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid #fff;\n }\n .bd-brand-item h1 {\n font-size: 4rem;\n }\n}\n\n\n//\n// Color swatches\n//\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden; // clearfix\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n border-radius: .25rem;\n\n @media (min-width: 768px) {\n width: 6rem;\n height: 6rem;\n }\n}\n\n// Docs colors\n.color-swatches {\n .bd-purple {\n background-color: $bd-purple;\n }\n .bd-purple-light {\n background-color: $bd-purple-light;\n }\n .bd-purple-lighter {\n background-color: #e5e1ea;\n }\n .bd-gray {\n background-color: #f9f9f9;\n }\n}\n","//\n// Docs color palette classes\n//\n\n@each $color, $value in $colors {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n\n@each $color, $value in $theme-colors {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n\n@each $color, $value in $grays {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n","// clipboard.js\n//\n// JS-based `Copy` buttons for code snippets.\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n\n + .highlight {\n margin-top: 0;\n }\n}\n\n.btn-clipboard {\n position: absolute;\n top: .5rem;\n right: .5rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n font-size: 75%;\n color: #818a91;\n cursor: pointer;\n background-color: transparent;\n border: 0;\n border-radius: .25rem;\n\n &:hover {\n color: #fff;\n background-color: #027de7;\n }\n}\n\n@media (min-width: 768px) {\n .bd-clipboard {\n display: block;\n }\n}\n","// stylelint-disable declaration-block-single-line-max-declarations\n\n.hll { background-color: #ffc; }\n.c { color: #999; }\n.k { color: #069; }\n.o { color: #555; }\n.cm { color: #999; }\n.cp { color: #099; }\n.c1 { color: #999; }\n.cs { color: #999; }\n.gd { background-color: #fcc; border: 1px solid #c00; }\n.ge { font-style: italic; }\n.gr { color: #f00; }\n.gh { color: #030; }\n.gi { background-color: #cfc; border: 1px solid #0c0; }\n.go { color: #aaa; }\n.gp { color: #009; }\n.gu { color: #030; }\n.gt { color: #9c6; }\n.kc { color: #069; }\n.kd { color: #069; }\n.kn { color: #069; }\n.kp { color: #069; }\n.kr { color: #069; }\n.kt { color: #078; }\n.m { color: #f60; }\n.s { color: #d44950; }\n.na { color: #4f9fcf; }\n.nb { color: #366; }\n.nc { color: #0a8; }\n.no { color: #360; }\n.nd { color: #99f; }\n.ni { color: #999; }\n.ne { color: #c00; }\n.nf { color: #c0f; }\n.nl { color: #99f; }\n.nn { color: #0cf; }\n.nt { color: #2f6f9f; }\n.nv { color: #033; }\n.ow { color: #000; }\n.w { color: #bbb; }\n.mf { color: #f60; }\n.mh { color: #f60; }\n.mi { color: #f60; }\n.mo { color: #f60; }\n.sb { color: #c30; }\n.sc { color: #c30; }\n.sd { font-style: italic; color: #c30; }\n.s2 { color: #c30; }\n.se { color: #c30; }\n.sh { color: #c30; }\n.si { color: #a00; }\n.sx { color: #c30; }\n.sr { color: #3aa; }\n.s1 { color: #c30; }\n.ss { color: #fc3; }\n.bp { color: #366; }\n.vc { color: #033; }\n.vg { color: #033; }\n.vi { color: #033; }\n.il { color: #f60; }\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt { color: #999; }\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n user-select: none;\n}\n",".anchorjs-link {\n font-weight: 400;\n color: rgba($link-color, .5);\n transition: color .16s linear;\n\n &:hover {\n color: $link-color;\n text-decoration: none;\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Docsearch overrides\n//\n// `!important` indicates overridden properties.\n.algolia-autocomplete {\n display: block !important;\n flex: 1;\n\n // Menu container\n .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, .1);\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175);\n\n @include media-breakpoint-up(md) {\n width: 175%;\n }\n\n // Caret\n &::before {\n display: none !important;\n }\n\n [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n }\n\n .ds-suggestions {\n margin-top: 0 !important;\n }\n }\n\n .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n }\n\n .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n font-size: .875rem !important;\n font-weight: 500 !important;\n color: $bd-purple-bright !important;\n border-bottom: 0 !important;\n }\n\n .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n }\n\n // Section header\n .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n }\n\n .algolia-docsearch-suggestion--content {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n\n // Vertical divider between column header and content\n &::before {\n display: none !important;\n }\n }\n\n .ds-suggestion {\n &:not(:first-child) {\n .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n }\n\n .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n }\n }\n\n .algolia-docsearch-suggestion--title {\n display: block;\n padding: .25rem 1rem !important;\n margin-bottom: 0 !important;\n font-size: .875rem !important;\n font-weight: 400 !important;\n }\n\n .algolia-docsearch-suggestion--text {\n padding: 0 1rem .5rem !important;\n margin-top: -.25rem;\n font-size: .875rem !important;\n font-weight: 400;\n line-height: 1.25 !important;\n }\n\n .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n font-size: .75rem !important;\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n\n .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n }\n\n .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, .12);\n }\n\n .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, .5) !important;\n }\n\n .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, .15) !important;\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/bootstrap-stack.png b/vendor/twbs/bootstrap/site/docs/4.1/assets/img/bootstrap-stack.png deleted file mode 100644 index 7cae17fe2..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/bootstrap-stack.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/browserconfig.xml b/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/browserconfig.xml deleted file mode 100644 index 810292778..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/browserconfig.xml +++ /dev/null @@ -1,11 +0,0 @@ ---- ---- - - - - - - #563d7c - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/manifest.json b/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/manifest.json deleted file mode 100644 index 88b2b7f41..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ ---- ---- -{ - "name": "Bootstrap", - "short_name": "Bootstrap", - "icons": [ - { - "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "start_url": "/", - "theme_color": "#563d7c", - "background_color": "#563d7c", - "display": "standalone" -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/docs.min.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/docs.min.js deleted file mode 100644 index cce24b993..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/docs.min.js +++ /dev/null @@ -1,28 +0,0 @@ -!function(e,t){"use strict";"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():(e.AnchorJS=t(),e.anchors=new e.AnchorJS)}(this,function(){"use strict";return function(e){function f(e){e.icon=e.hasOwnProperty("icon")?e.icon:"",e.visible=e.hasOwnProperty("visible")?e.visible:"hover",e.placement=e.hasOwnProperty("placement")?e.placement:"right",e.ariaLabel=e.hasOwnProperty("ariaLabel")?e.ariaLabel:"Anchor",e.class=e.hasOwnProperty("class")?e.class:"",e.truncate=e.hasOwnProperty("truncate")?Math.floor(e.truncate):64}function A(e){var t;if("string"==typeof e||e instanceof String)t=[].slice.call(document.querySelectorAll(e));else{if(!(Array.isArray(e)||e instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");t=[].slice.call(e)}return t}function p(){if(null===document.head.querySelector("style.anchorjs")){var e,t=document.createElement("style");t.className="anchorjs",t.appendChild(document.createTextNode("")),void 0===(e=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(t):document.head.insertBefore(t,e),t.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",t.sheet.cssRules.length),t.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",t.sheet.cssRules.length),t.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",t.sheet.cssRules.length),t.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',t.sheet.cssRules.length)}}this.options=e||{},this.elements=[],f(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(e){var t,n,r,i,o,a,s,l,c,u,h,d=[];if(f(this.options),"touch"===(h=this.options.visible)&&(h=this.isTouchDevice()?"always":"hover"),e||(e="h2, h3, h4, h5, h6"),0===(t=A(e)).length)return this;for(p(),n=document.querySelectorAll("[id]"),r=[].map.call(n,function(e){return e.id}),o=0;o\]\.\/\(\)\*\\]/g;return this.options.truncate||f(this.options),e.trim().replace(/\'/gi,"").replace(t,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(e){var t=e.firstChild&&(" "+e.firstChild.className+" ").indexOf(" anchorjs-link ")>-1,n=e.lastChild&&(" "+e.lastChild.className+" ").indexOf(" anchorjs-link ")>-1;return t||n||!1}}}); -/*! - * clipboard.js v2.0.0 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.ClipboardJS=t():e.ClipboardJS=t()}(this,function(){return function(n){function r(e){if(i[e])return i[e].exports;var t=i[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,r),t.l=!0,t.exports}var i={};return r.m=n,r.c=i,r.i=function(e){return e},r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:n})},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=3)}([function(n,r,i){var o,a,s;!function(e,t){a=[n,i(7)],o=t,void 0!==(s="function"==typeof o?o.apply(r,a):o)&&(n.exports=s)}(0,function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var r=function(e){return e&&e.__esModule?e:{default:e}}(t),i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function r(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,r.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,r.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":i(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),t}();e.exports=a})},function(e,t,n){function r(e,t,n){if(!e&&!t&&!n)throw new Error("Missing required arguments");if(!s.string(t))throw new TypeError("Second argument must be a String");if(!s.fn(n))throw new TypeError("Third argument must be a Function");if(s.node(e))return i(e,t,n);if(s.nodeList(e))return o(e,t,n);if(s.string(e))return a(e,t,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(e,t,n){return e.addEventListener(t,n),{destroy:function(){e.removeEventListener(t,n)}}}function o(e,t,n){return Array.prototype.forEach.call(e,function(e){e.addEventListener(t,n)}),{destroy:function(){Array.prototype.forEach.call(e,function(e){e.removeEventListener(t,n)})}}}function a(e,t,n){return l(document.body,e,t,n)}var s=n(6),l=n(5);e.exports=r},function(e,t){function n(){}n.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){function r(){i.off(e,r),t.apply(n,arguments)}var i=this;return r._=t,this.on(e,r,n)},emit:function(e){var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,i=n.length;for(r;r0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===d(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=(0,h.default)(e,"click",function(e){return t.onClick(e)})}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new c.default({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return l("action",e)}},{key:"defaultTarget",value:function(e){var t=l("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return l("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach(function(e){n=n&&!!document.queryCommandSupported(e)}),n}}]),r}(u.default);e.exports=A})},function(e,t){function n(e,t){for(;e&&e.nodeType!==r;){if("function"==typeof e.matches&&e.matches(t))return e;e=e.parentNode}}var r=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}e.exports=n},function(e,t,n){function o(e,t,n,r,i){var o=a.apply(this,arguments);return e.addEventListener(n,o,i),{destroy:function(){e.removeEventListener(n,o,i)}}}function r(e,t,n,r,i){return"function"==typeof e.addEventListener?o.apply(null,arguments):"function"==typeof n?o.bind(null,document).apply(null,arguments):("string"==typeof e&&(e=document.querySelectorAll(e)),Array.prototype.map.call(e,function(e){return o(e,t,n,r,i)}))}function a(t,n,e,r){return function(e){e.delegateTarget=i(e.target,n),e.delegateTarget&&r.call(t,e)}}var i=n(4);e.exports=r},function(e,n){n.node=function(e){return void 0!==e&&e instanceof HTMLElement&&1===e.nodeType},n.nodeList=function(e){var t=Object.prototype.toString.call(e);return void 0!==e&&("[object NodeList]"===t||"[object HTMLCollection]"===t)&&"length"in e&&(0===e.length||n.node(e[0]))},n.string=function(e){return"string"==typeof e||e instanceof String},n.fn=function(e){return"[object Function]"===Object.prototype.toString.call(e)}},function(e,t){function n(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),i=document.createRange();i.selectNodeContents(e),r.removeAllRanges(),r.addRange(i),t=r.toString()}return t}e.exports=n}])}); -/*! - -Holder - client side image placeholders -Version 2.9.4+cabil -© 2016 Ivan Malopinsky - http://imsky.co - -Site: http://holderjs.com -Issues: https://github.com/imsky/holder/issues -License: MIT - -*/ -!function(i){if(i.document){var o=i.document;o.querySelectorAll||(o.querySelectorAll=function(e){var t,n=o.createElement("style"),r=[];for(o.documentElement.firstChild.appendChild(n),o._qsa=[],n.styleSheet.cssText=e+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",i.scrollBy(0,0),n.parentNode.removeChild(n);o._qsa.length;)t=o._qsa.shift(),t.style.removeAttribute("x-qsa"),r.push(t);return o._qsa=null,r}),o.querySelector||(o.querySelector=function(e){var t=o.querySelectorAll(e);return t.length?t[0]:null}),o.getElementsByClassName||(o.getElementsByClassName=function(e){return e=String(e).replace(/^|\s+/g,"."),o.querySelectorAll(e)}),Object.keys||(Object.keys=function(e){if(e!==Object(e))throw TypeError("Object.keys called on non-object");var t,n=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&n.push(t);return n}),Array.prototype.forEach||(Array.prototype.forEach=function(e){if(void 0===this||null===this)throw TypeError();var t=Object(this),n=t.length>>>0;if("function"!=typeof e)throw TypeError();var r,i=arguments[1];for(r=0;r>16&255)),r.push(String.fromCharCode(i>>8&255)),r.push(String.fromCharCode(255&i)),o=0,i=0),n+=1;return 12===o?(i>>=4,r.push(String.fromCharCode(255&i))):18===o&&(i>>=2,r.push(String.fromCharCode(i>>8&255)),r.push(String.fromCharCode(255&i))),r.join("")},e.btoa=e.btoa||function(e){e=String(e);var t,n,r,i,o,a,s,l=0,c=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;l>2,o=(3&t)<<4|n>>4,a=(15&n)<<2|r>>6,s=63&r,l===e.length+2?(a=64,s=64):l===e.length+1&&(s=64),c.push(u.charAt(i),u.charAt(o),u.charAt(a),u.charAt(s));return c.join("")}}(i),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in i==!1&&(i.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in i.performance==!1){var e=Date.now();performance.timing&&performance.timing.navigationStart&&(e=performance.timing.navigationStart),i.performance.now=function(){return Date.now()-e}}}(),i.requestAnimationFrame||(i.webkitRequestAnimationFrame&&i.webkitCancelAnimationFrame?!function(t){t.requestAnimationFrame=function(e){return webkitRequestAnimationFrame(function(){e(t.performance.now())})},t.cancelAnimationFrame=t.webkitCancelAnimationFrame}(i):i.mozRequestAnimationFrame&&i.mozCancelAnimationFrame?!function(t){t.requestAnimationFrame=function(e){return mozRequestAnimationFrame(function(){e(t.performance.now())})},t.cancelAnimationFrame=t.mozCancelAnimationFrame}(i):!function(t){t.requestAnimationFrame=function(e){return t.setTimeout(e,1e3/60)},t.cancelAnimationFrame=t.clearTimeout}(i))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return function(n){function r(e){if(i[e])return i[e].exports;var t=i[e]={exports:{},id:e,loaded:!1};return n[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}var i={};return r.m=n,r.c=i,r.p="",r(0)}([function(e,t,n){e.exports=n(1)},function(L,e,F){(function(h){function o(e,t,n,r){var i=d(n.substr(n.lastIndexOf(e.domain)),e);i&&f({mode:null,el:r,flags:i,engineSettings:t})}function d(e,t){var n={theme:E(O.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},r=e.indexOf("?"),i=[e];r!==-1&&(i=[e.slice(0,r),e.slice(r+1)]);var o=i[0].split("/");n.holderURL=e;var a=o[1],s=a.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=a.indexOf("p")!==-1,n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===i.length){var l=A.parse(i[1]);if(b.truthy(l.ratio)){n.fluid=!0;var c=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(100*(u/c)),c=100,n.dimensions.width=c+"%",n.dimensions.height=u+"%"}if(n.auto=b.truthy(l.auto),l.bg&&(n.theme.bg=b.parseColor(l.bg)),l.fg&&(n.theme.fg=b.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=E(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&(n.size=l.size),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=b.truthy(l.nowrap),n.outline=b.truthy(l.outline),b.truthy(l.random)){O.vars.cache.themeKeys=O.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var h=O.vars.cache.themeKeys[0|Math.random()*O.vars.cache.themeKeys.length];n.theme=E(n.instanceOptions.themes[h],null)}}return n}function f(e){var t=e.mode,n=e.el,r=e.flags,i=e.engineSettings,o=r.dimensions,a=r.theme,s=o.width+"x"+o.height;t=null==t?r.fluid?"fluid":"image":t;var l=/holder_([a-z]+)/g,c=!1;if(null!=r.text&&(a.text=r.text,"object"===n.nodeName.toLowerCase())){for(var u=a.text.split("\\n"),h=0;h1){var v,y=0,b=0,w=0;m=new s.Group("line"+w),"left"!==e.align&&"right"!==e.align||(o=e.width*(1-2*(1-r)));for(var x=0;x=o||S===!0)&&(t(A,m,y,A.properties.leading),A.add(m),y=0,b+=A.properties.leading,w+=1,m=new s.Group("line"+w),m.y=b),S!==!0&&(g.moveTo(y,0),y+=p.spaceWidth+E.width,m.add(g))}if(t(A,m,y,A.properties.leading),A.add(m),"left"===e.align)A.moveTo(e.width-i,null,null);else if("right"===e.align){for(v in A.children)m=A.children[v],m.moveTo(e.width-m.width,null,null);A.moveTo(0-(e.width-i),null,null)}else{for(v in A.children)m=A.children[v],m.moveTo((A.width-m.width)/2,null,null);A.moveTo((e.width-A.width)/2,null,null)}A.moveTo(null,(e.height-A.height)/2,null),(e.height-A.height)/2<0&&A.moveTo(null,0,null)}else g=new s.Text(e.text),m=new s.Group("line0"),m.add(g),A.add(m),"left"===e.align?A.moveTo(e.width-i,null,null):"right"===e.align?A.moveTo(0-(e.width-i),null,null):A.moveTo((e.width-p.boundingBox.width)/2,null,null),A.moveTo(null,(e.height-p.boundingBox.height)/2,null);return a}function C(e,t,n,r){var i=parseInt(e,10),o=parseInt(t,10),a=Math.max(i,o),s=Math.min(i,o),l=.8*Math.min(s,a*r);return Math.round(Math.max(n,l))}function v(e){var t;t=null==e||null==e.nodeType?O.vars.resizableImages:[e];for(var n=0,r=t.length;n1){v.nodeValue="";for(var A=0;A=0?t:1)}function o(e){w?i(e):x.push(e)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function e(){document.removeEventListener("DOMContentLoaded",e,!1),document.readyState="complete"},!1),document.readyState="loading");var a=e.document,s=a.documentElement,l="load",c=!1,u="on"+l,h="complete",d="readyState",f="attachEvent",A="detachEvent",p="addEventListener",g="DOMContentLoaded",m="onreadystatechange",v="removeEventListener",y=p in a,b=c,w=c,x=[];if(a[d]===h)i(n);else if(y)a[p](g,t,c),e[p](l,t,c);else{a[f](m,t),e[f](u,t);try{b=null==e.frameElement&&s}catch(e){}b&&b.doScroll&&!function t(){if(!w){try{b.doScroll("left")}catch(e){return i(t,50)}r(),n()}}()}return o.version="1.4.0",o.isReady=function(){return w},o}e.exports="undefined"!=typeof window&&n(window)},function(e,t,n){var o=encodeURIComponent,c=decodeURIComponent,u=n(4),a=n(5),h=/(\w+)\[(\d+)\]/,d=/\w+\.\w+/;t.parse=function(e){if("string"!=typeof e)return{};if(e=u(e),""===e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t={},n=e.split("&"),r=0;r=0;r--)n=e.charCodeAt(r),n>128?t.unshift(["&#",n,";"].join("")):t.unshift(e[r]);return t.join("")},t.imageExists=function(e,t){var n=new Image;n.onerror=function(){t.call(this,!1)},n.onload=function(){t.call(this,!0)},n.src=e},t.decodeHtmlEntity=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(t)})},t.dimensionCheck=function(e){var t={height:e.clientHeight,width:e.clientWidth};return!(!t.height||!t.width)&&t},t.truthy=function(e){return"string"==typeof e?"true"===e||"yes"===e||"1"===e||"on"===e||"✓"===e:!!e},t.parseColor=function(e){var t,n=/(^(?:#?)[0-9a-f]{6}$)|(^(?:#?)[0-9a-f]{3}$)/i,r=/^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/,i=/^rgba\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0\.\d{1,}|1)\)$/,o=e.match(n);return null!==o?(t=o[1]||o[2],"#"!==t[0]?"#"+t:t):(o=e.match(r),null!==o?t="rgb("+o.slice(1).join(",")+")":(o=e.match(i),null!==o?t="rgba("+o.slice(1).join(",")+")":null))},t.canvasRatio=function(){var e=1,t=1;if(i.document){var n=i.document.createElement("canvas");if(n.getContext){var r=n.getContext("2d");e=i.devicePixelRatio||1,t=r.webkitBackingStorePixelRatio||r.mozBackingStorePixelRatio||r.msBackingStorePixelRatio||r.oBackingStorePixelRatio||r.backingStorePixelRatio||1}}return e/t}}).call(t,function(){return this}())},function(e,t,n){(function(c){var u=n(9),s="http://www.w3.org/2000/svg",l=8;t.initSVG=function(e,t,n){var r,i,o=!1;e&&e.querySelector?(i=e.querySelector("style"),null===i&&(o=!0)):(e=u.newEl("svg",s),o=!0),o&&(r=u.newEl("defs",s),i=u.newEl("style",s),u.setAttr(i,{type:"text/css"}),r.appendChild(i),e.appendChild(r)),e.webkitMatchesSelector&&e.setAttribute("xmlns",s);for(var a=0;a=0;a--){var s=o.createProcessingInstruction("xml-stylesheet",'href="'+i[a]+'" rel="stylesheet"');o.insertBefore(s,o.firstChild)}o.removeChild(o.documentElement),r=n.serializeToString(o)}var l=n.serializeToString(e);return l=l.replace(/\&(\#[0-9]{2,}\;)/g,"&$1"),r+l}}}).call(t,function(){return this}())},function(e,t){(function(n){t.newEl=function(e,t){if(n.document)return null==t?n.document.createElement(e):n.document.createElementNS(t,e)},t.setAttr=function(e,t){for(var n in t)e.setAttribute(n,t[n])},t.createXML=function(){if(n.DOMParser)return(new DOMParser).parseFromString("","application/xml")},t.getNodeArray=function(e){var t=null;return"string"==typeof e?t=document.querySelectorAll(e):n.NodeList&&e instanceof n.NodeList?t=e:n.Node&&e instanceof n.Node?t=[e]:n.HTMLCollection&&e instanceof n.HTMLCollection?t=e:e instanceof Array?t=e:null===e&&(t=[]),t=Array.prototype.slice.call(t)}}).call(t,function(){return this}())},function(e,t){var s=function(e,t){"string"==typeof e&&(this.original=e,"#"===e.charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))};s.rgb2hex=function(e,t,n){function r(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}return[e,t,n].map(r).join("")},s.hsl2rgb=function(e,t,n){var r=e/60,i=(1-Math.abs(2*n-1))*t,o=i*(1-Math.abs(parseInt(r)%2-1)),a=n-i/2,s=0,l=0,c=0;return r>=0&&r<1?(s=i,l=o):r>=1&&r<2?(s=o,l=i):r>=2&&r<3?(l=i,c=o):r>=3&&r<4?(l=o,c=i):r>=4&&r<5?(s=o,c=i):r>=5&&r<6&&(s=i,c=o),s+=a,l+=a,c+=a,s=parseInt(255*s),l=parseInt(255*l),c=parseInt(255*c),[s,l,c]},s.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,r=255&this.raw,i=.2126*t+.7152*n+.0722*r,o=-.09991*t-.33609*n+.436*r,a=.615*t-.55861*n-.05639*r;return this.rgb={r:t,g:n,b:r},this.yuv={y:i,u:o,v:a},this},s.prototype.lighten=function(e){var t=Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1),n=255*t|0,r=Math.min(255,Math.max(0,this.rgb.r+n)),i=Math.min(255,Math.max(0,this.rgb.g+n)),o=Math.min(255,Math.max(0,this.rgb.b+n)),a=s.rgb2hex(r,i,o);return new s(a)},s.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},s.prototype.lighterThan=function(e){return e instanceof s||(e=new s(e)),this.yuv.y>e.yuv.y},s.prototype.blendAlpha=function(e){e instanceof s||(e=new s(e));var t=e,n=this,r=t.alpha*t.rgb.r+(1-t.alpha)*n.rgb.r,i=t.alpha*t.rgb.g+(1-t.alpha)*n.rgb.g,o=t.alpha*t.rgb.b+(1-t.alpha)*n.rgb.b;return new s(s.rgb2hex(r,i,o))},e.exports=s},function(e,t){e.exports={version:"2.9.4",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){function w(e,t){return T.element({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}function x(e){return i.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}function E(e,t,n){var r=n/2;return["M",r,r,"H",e-r,"V",t-r,"H",r,"V",0,"M",0,r,"L",e,t-r,"M",0,t-r,"L",e,r].join(" ")}var S=n(13),C=n(8),r=n(11),i=n(7),k=r.svg_ns,T={element:function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]}};e.exports=function(e,t){var n=t.engineSettings,r=n.stylesheets,i=r.map(function(e){return''}).join("\n"),o="holder_"+Number(new Date).toString(16),a=e.root,s=a.children.holderTextGroup,l="#"+o+" text { "+x(s.properties)+" } ";s.y+=.8*s.textPositionData.boundingBox.height;var c=[];Object.keys(s.children).forEach(function(e){var o=s.children[e];Object.keys(o.children).forEach(function(e){var t=o.children[e],n=s.x+o.x+t.x,r=s.y+o.y+t.y,i=T.element({tag:"text",content:t.properties.text,x:n,y:r});c.push(i)})});var u=T.element({tag:"g",content:c}),h=null;if(a.children.holderBg.properties.outline){var d=a.children.holderBg.properties.outline;h=T.element({tag:"path",d:E(a.children.holderBg.width,a.children.holderBg.height,d.width),"stroke-width":d.width,stroke:d.fill,fill:"none"})}var f=w(a.children.holderBg,"rect"),A=[];A.push(f),d&&A.push(h),A.push(u);var p=T.element({tag:"g",id:o,content:A}),g=T.element({tag:"style",content:l,type:"text/css"}),m=T.element({tag:"defs",content:g}),v=T.element({tag:"svg",content:[m,p],width:a.properties.width,height:a.properties.height,xmlns:k,viewBox:[0,0,a.properties.width,a.properties.height].join(" "),preserveAspectRatio:"none"}),y=S(v);y=i+y[0];var b=C.svgStringToDataURI(y,"background"===t.mode);return b}},function(e,t,n){n(14);e.exports=function e(t,n,a){"use strict";function r(e){var t=e.match(/^[\w-]+/),n={tag:t?t[0]:"div",attr:{},children:[]},r=e.match(/#([\w-]+)/),i=e.match(/\$([\w-]+)/),o=e.match(/\.[\w-]+/g);return r&&(n.attr.id=r[1],a[r[1]]=n),i&&(a[i[1]]=n),o&&(n.attr["class"]=o.join(" ").replace(/\./g,"")),e.match(/&$/g)&&(f=!1),n}function i(e,t){if(null!==t&&t!==!1&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}function o(e){return e||0===e?String(e).replace(/&/g,"&").replace(/"/g,"""):""}function s(e){return String(e).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}var l,c,u,h,d=1,f=!0;if(a=a||{},"string"==typeof t[0])t[0]=r(t[0]);else{if(!Array.isArray(t[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(t[0]));d=0}for(;d",t[0]=l}return a[0]=t[0],u&&u(t[0]),a}},function(e,t){"use strict";function n(e){var t=""+e,n=s.exec(t);if(!n)return t;var r,i="",o=0,a=0;for(o=n.index;o]/;e.exports=n},function(e,t,n){var r=n(9),m=n(7);e.exports=function(){var p=r.newEl("canvas"),g=null;return function(e){null==g&&(g=p.getContext("2d"));var t=m.canvasRatio(),n=e.root;p.width=t*n.properties.width,p.height=t*n.properties.height,g.textBaseline="middle";var r=n.children.holderBg,i=t*r.width,o=t*r.height,a=2,s=a/2;g.fillStyle=r.properties.fill,g.fillRect(0,0,i,o),r.properties.outline&&(g.strokeStyle=r.properties.outline.fill,g.lineWidth=r.properties.outline.width,g.moveTo(s,s),g.lineTo(i-s,s),g.lineTo(i-s,o-s),g.lineTo(s,o-s),g.lineTo(s,s),g.moveTo(0,s),g.lineTo(i,o-s),g.moveTo(0,o-s),g.lineTo(i,s),g.stroke());var l=n.children.holderTextGroup;g.font=l.properties.font.weight+" "+t*l.properties.font.size+l.properties.font.units+" "+l.properties.font.family+", monospace",g.fillStyle=l.properties.fill;for(var c in l.children){var u=l.children[c];for(var h in u.children){var d=u.children[h],f=t*(l.x+u.x+d.x),A=t*(l.y+u.y+d.y+l.properties.leading/2);g.fillText(d.properties.text,f,A)}}return p.toDataURL("image/png")}}()}])}),function(e,t){t&&(Holder=e.Holder)}(this,"undefined"!=typeof Meteor&&"undefined"!=typeof Package); -/*! - * JavaScript for Bootstrap's docs (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. For - * details, see https://creativecommons.org/licenses/by/3.0/. - */ -(function(i){"use strict";i(function(){i(".tooltip-demo").tooltip({selector:'[data-toggle="tooltip"]',container:"body"});i('[data-toggle="popover"]').popover();i(".tooltip-test").tooltip();i(".popover-test").popover();i('.bd-example-indeterminate [type="checkbox"]').prop("indeterminate",true);i('.bd-content [href="#"]').click(function(e){e.preventDefault()});i("#exampleModal").on("show.bs.modal",function(e){var t=i(e.relatedTarget);var n=t.data("whatever");var r=i(this);r.find(".modal-title").text("New message to "+n);r.find(".modal-body input").val(n)});i(".bd-toggle-animated-progress").on("click",function(){i(this).siblings(".progress").find(".progress-bar-striped").toggleClass("progress-bar-animated")});i("figure.highlight, div.highlight").each(function(){var e='
';i(this).before(e);i(".btn-clipboard").tooltip().on("mouseleave",function(){i(this).tooltip("hide")})});var e=new ClipboardJS(".btn-clipboard",{target:function(e){return e.parentNode.nextElementSibling}});e.on("success",function(e){i(e.trigger).attr("title","Copied!").tooltip("_fixTitle").tooltip("show").attr("title","Copy to clipboard").tooltip("_fixTitle");e.clearSelection()});e.on("error",function(e){var t=/Mac/i.test(navigator.userAgent)?"⌘":"Ctrl-";var n="Press "+t+"C to copy";i(e.trigger).attr("title",n).tooltip("_fixTitle").tooltip("show").attr("title","Copy to clipboard").tooltip("_fixTitle")});anchors.options={icon:"#"};anchors.add(".bd-content > h2, .bd-content > h3, .bd-content > h4, .bd-content > h5");i(".bd-content > h2, .bd-content > h3, .bd-content > h4, .bd-content > h5").wrapInner("
");Holder.addTheme("gray",{bg:"#777",fg:"rgba(255,255,255,.75)",font:"Helvetica",fontweight:"normal"})})})(jQuery);(function(){"use strict";function e(){var e=/MSIE ([0-9.]+)/.exec(window.navigator.userAgent);if(e===null){return null}var t=parseInt(e[1],10);var n=Math.floor(t);return n}function t(){var e=new Function("/*@cc_on return @_jscript_version; @*/")();if(typeof e==="undefined"){return 11}if(e<9){return 8}return e}var n=window.navigator.userAgent;if(n.indexOf("Opera")>-1||n.indexOf("Presto")>-1){return}var r=e();if(r===null){return}var i=t();if(r!==i){window.alert("WARNING: You appear to be using IE"+i+" in IE"+r+" emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!")}})();(function(){"use strict";if("serviceWorker"in navigator){window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.js").then(function(e){console.log("ServiceWorker registration successful with scope: ",e.scope)}).catch(function(e){console.log("ServiceWorker registration failed: ",e)})})}else{console.log("Service workers are not supported.")}})();(function(){"use strict";if(!window.docsearch){return}var r=document.getElementById("search-input");var e=r.getAttribute("data-docs-version");window.docsearch({apiKey:"5990ad008512000bba2cf951ccf0332f",indexName:"bootstrap",inputSelector:"#search-input",algoliaOptions:{facetFilters:["version:"+e]},handleSelected:function(e,t,n){var r=n.url;r=n.isLvl1?r.split("#")[0]:r;window.location.href=r},transformData:function(e){return e.map(function(e){var t=r.getAttribute("data-siteurl");var n=/^https?:\/\/getbootstrap\.com/;e.url=t.match(n)?e.url:e.url.replace(n,"");return e})},debug:false})})(); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/pwa.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/pwa.js deleted file mode 100644 index 142f89915..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/pwa.js +++ /dev/null @@ -1,21 +0,0 @@ -// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT -// IT'S ALL JUST JUNK FOR OUR DOCS! -// ++++++++++++++++++++++++++++++++++++++++++ - -/* eslint no-console:off */ - -(function () { - 'use strict' - - if ('serviceWorker' in navigator) { - window.addEventListener('load', function () { - navigator.serviceWorker.register('/sw.js').then(function (registration) { // eslint-disable-line compat/compat - console.log('ServiceWorker registration successful with scope: ', registration.scope) - }).catch(function (err) { - console.log('ServiceWorker registration failed: ', err) - }) - }) - } else { - console.log('Service workers are not supported.') - } -}()) diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/anchor.min.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/anchor.min.js deleted file mode 100644 index ee4e3b3f4..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/anchor.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * AnchorJS - v4.1.0 - 2017-09-20 - * https://github.com/bryanbraun/anchorjs - * Copyright (c) 2017 Bryan Braun; Licensed MIT - */ -!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function e(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64}function t(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}function i(){if(null===document.head.querySelector("style.anchorjs")){var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}this.options=A||{},this.elements=[],e(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var n,o,s,a,r,c,h,l,u,d,f,p=[];if(e(this.options),"touch"===(f=this.options.visible)&&(f=this.isTouchDevice()?"always":"hover"),A||(A="h2, h3, h4, h5, h6"),0===(n=t(A)).length)return this;for(i(),o=document.querySelectorAll("[id]"),s=[].map.call(o,function(A){return A.id}),r=0;r\]\.\/\(\)\*\\]/g;return this.options.truncate||e(this.options),A.trim().replace(/\'/gi,"").replace(t,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&(" "+A.firstChild.className+" ").indexOf(" anchorjs-link ")>-1,t=A.lastChild&&(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ")>-1;return e||t||!1}}}); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/clipboard.min.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/clipboard.min.js deleted file mode 100644 index b00ee5153..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.0 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=3)}([function(t,e,n){var o,r,i;!function(a,c){r=[t,n(7)],o=c,void 0!==(i="function"==typeof o?o.apply(e,r):o)&&(t.exports=i)}(0,function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var o=function(t){return t&&t.__esModule?t:{default:t}}(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),t}();t.exports=a})},function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return r(t,e,n);if(c.nodeList(t))return i(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function r(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return u(document.body,t,e,n)}var c=n(6),u=n(5);t.exports=o},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){r.off(t,o),e.apply(n,arguments)}var r=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;for(o;o0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===d(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,f.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return u("action",t)}},{key:"defaultTarget",value:function(t){var e=u("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return u("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),e}(s.default);t.exports=p})},function(t,e){function n(t,e){for(;t&&t.nodeType!==o;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var o=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}t.exports=n},function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function r(t,e,n,r,i){return"function"==typeof t.addEventListener?o.apply(null,arguments):"function"==typeof n?o.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return o(t,e,n,r,i)}))}function i(t,e,n,o){return function(n){n.delegateTarget=a(n.target,e),n.delegateTarget&&o.call(t,n)}}var a=n(4);t.exports=r},function(t,e){e.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},e.nodeList=function(t){var n=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in t&&(0===t.length||e.node(t[0]))},e.string=function(t){return"string"==typeof t||t instanceof String},e.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e){function n(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}t.exports=n}])}); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/holder.min.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/holder.min.js deleted file mode 100644 index 62255af4f..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/holder.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/*! - -Holder - client side image placeholders -Version 2.9.4+cabil -© 2016 Ivan Malopinsky - http://imsky.co - -Site: http://holderjs.com -Issues: https://github.com/imsky/holder/issues -License: MIT - -*/ -!function(e){if(e.document){var t=e.document;t.querySelectorAll||(t.querySelectorAll=function(n){var r,i=t.createElement("style"),o=[];for(t.documentElement.firstChild.appendChild(i),t._qsa=[],i.styleSheet.cssText=n+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",e.scrollBy(0,0),i.parentNode.removeChild(i);t._qsa.length;)r=t._qsa.shift(),r.style.removeAttribute("x-qsa"),o.push(r);return t._qsa=null,o}),t.querySelector||(t.querySelector=function(e){var n=t.querySelectorAll(e);return n.length?n[0]:null}),t.getElementsByClassName||(t.getElementsByClassName=function(e){return e=String(e).replace(/^|\s+/g,"."),t.querySelectorAll(e)}),Object.keys||(Object.keys=function(e){if(e!==Object(e))throw TypeError("Object.keys called on non-object");var t,n=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&n.push(t);return n}),Array.prototype.forEach||(Array.prototype.forEach=function(e){if(void 0===this||null===this)throw TypeError();var t=Object(this),n=t.length>>>0;if("function"!=typeof e)throw TypeError();var r,i=arguments[1];for(r=0;r>16&255)),i.push(String.fromCharCode(o>>8&255)),i.push(String.fromCharCode(255&o)),a=0,o=0),r+=1;return 12===a?(o>>=4,i.push(String.fromCharCode(255&o))):18===a&&(o>>=2,i.push(String.fromCharCode(o>>8&255)),i.push(String.fromCharCode(255&o))),i.join("")},e.btoa=e.btoa||function(e){e=String(e);var n,r,i,o,a,s,l,h=0,u=[];if(/[^\x00-\xFF]/.test(e))throw Error("InvalidCharacterError");for(;h>2,a=(3&n)<<4|r>>4,s=(15&r)<<2|i>>6,l=63&i,h===e.length+2?(s=64,l=64):h===e.length+1&&(l=64),u.push(t.charAt(o),t.charAt(a),t.charAt(s),t.charAt(l));return u.join("")}}(e),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(e){var t=this.__proto__||this.constructor.prototype;return e in this&&(!(e in t)||t[e]!==this[e])}),function(){if("performance"in e==!1&&(e.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in e.performance==!1){var t=Date.now();performance.timing&&performance.timing.navigationStart&&(t=performance.timing.navigationStart),e.performance.now=function(){return Date.now()-t}}}(),e.requestAnimationFrame||(e.webkitRequestAnimationFrame&&e.webkitCancelAnimationFrame?!function(e){e.requestAnimationFrame=function(t){return webkitRequestAnimationFrame(function(){t(e.performance.now())})},e.cancelAnimationFrame=e.webkitCancelAnimationFrame}(e):e.mozRequestAnimationFrame&&e.mozCancelAnimationFrame?!function(e){e.requestAnimationFrame=function(t){return mozRequestAnimationFrame(function(){t(e.performance.now())})},e.cancelAnimationFrame=e.mozCancelAnimationFrame}(e):!function(e){e.requestAnimationFrame=function(t){return e.setTimeout(t,1e3/60)},e.cancelAnimationFrame=e.clearTimeout}(e))}}(this),function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Holder=t():e.Holder=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){(function(t){function r(e,t,n,r){var a=i(n.substr(n.lastIndexOf(e.domain)),e);a&&o({mode:null,el:r,flags:a,engineSettings:t})}function i(e,t){var n={theme:k(O.settings.themes.gray,null),stylesheets:t.stylesheets,instanceOptions:t},r=e.indexOf("?"),i=[e];r!==-1&&(i=[e.slice(0,r),e.slice(r+1)]);var o=i[0].split("/");n.holderURL=e;var a=o[1],s=a.match(/([\d]+p?)x([\d]+p?)/);if(!s)return!1;if(n.fluid=a.indexOf("p")!==-1,n.dimensions={width:s[1].replace("p","%"),height:s[2].replace("p","%")},2===i.length){var l=v.parse(i[1]);if(w.truthy(l.ratio)){n.fluid=!0;var h=parseFloat(n.dimensions.width.replace("%","")),u=parseFloat(n.dimensions.height.replace("%",""));u=Math.floor(100*(u/h)),h=100,n.dimensions.width=h+"%",n.dimensions.height=u+"%"}if(n.auto=w.truthy(l.auto),l.bg&&(n.theme.bg=w.parseColor(l.bg)),l.fg&&(n.theme.fg=w.parseColor(l.fg)),l.bg&&!l.fg&&(n.autoFg=!0),l.theme&&n.instanceOptions.themes.hasOwnProperty(l.theme)&&(n.theme=k(n.instanceOptions.themes[l.theme],null)),l.text&&(n.text=l.text),l.textmode&&(n.textmode=l.textmode),l.size&&(n.size=l.size),l.font&&(n.font=l.font),l.align&&(n.align=l.align),l.lineWrap&&(n.lineWrap=l.lineWrap),n.nowrap=w.truthy(l.nowrap),n.outline=w.truthy(l.outline),w.truthy(l.random)){O.vars.cache.themeKeys=O.vars.cache.themeKeys||Object.keys(n.instanceOptions.themes);var c=O.vars.cache.themeKeys[0|Math.random()*O.vars.cache.themeKeys.length];n.theme=k(n.instanceOptions.themes[c],null)}}return n}function o(e){var t=e.mode,n=e.el,r=e.flags,i=e.engineSettings,o=r.dimensions,s=r.theme,l=o.width+"x"+o.height;t=null==t?r.fluid?"fluid":"image":t;var c=/holder_([a-z]+)/g,d=!1;if(null!=r.text&&(s.text=r.text,"object"===n.nodeName.toLowerCase())){for(var f=s.text.split("\\n"),p=0;p1){var b,x=0,A=0,C=0;w=new s.Group("line"+C),"left"!==e.align&&"right"!==e.align||(o=e.width*(1-2*(1-r)));for(var E=0;E=o||T===!0)&&(t(g,w,x,g.properties.leading),g.add(w),x=0,A+=g.properties.leading,C+=1,w=new s.Group("line"+C),w.y=A),T!==!0&&(v.moveTo(x,0),x+=m.spaceWidth+k.width,w.add(v))}if(t(g,w,x,g.properties.leading),g.add(w),"left"===e.align)g.moveTo(e.width-i,null,null);else if("right"===e.align){for(b in g.children)w=g.children[b],w.moveTo(e.width-w.width,null,null);g.moveTo(0-(e.width-i),null,null)}else{for(b in g.children)w=g.children[b],w.moveTo((g.width-w.width)/2,null,null);g.moveTo((e.width-g.width)/2,null,null)}g.moveTo(null,(e.height-g.height)/2,null),(e.height-g.height)/2<0&&g.moveTo(null,0,null)}else v=new s.Text(e.text),w=new s.Group("line0"),w.add(v),g.add(w),"left"===e.align?g.moveTo(e.width-i,null,null):"right"===e.align?g.moveTo(0-(e.width-i),null,null):g.moveTo((e.width-m.boundingBox.width)/2,null,null),g.moveTo(null,(e.height-m.boundingBox.height)/2,null);return a}function l(e,t,n,r){var i=parseInt(e,10),o=parseInt(t,10),a=Math.max(i,o),s=Math.min(i,o),l=.8*Math.min(s,a*r);return Math.round(Math.max(n,l))}function h(e){var t;t=null==e||null==e.nodeType?O.vars.resizableImages:[e];for(var n=0,r=t.length;n1){n.nodeValue="";for(var v=0;v=0?t:1)}function o(e){x?i(e):S.push(e)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function C(){document.removeEventListener("DOMContentLoaded",C,!1),document.readyState="complete"},!1),document.readyState="loading");var a=e.document,s=a.documentElement,l="load",h=!1,u="on"+l,c="complete",d="readyState",f="attachEvent",p="detachEvent",g="addEventListener",m="DOMContentLoaded",v="onreadystatechange",y="removeEventListener",w=g in a,b=h,x=h,S=[];if(a[d]===c)i(t);else if(w)a[g](m,n,h),e[g](l,n,h);else{a[f](v,n),e[f](u,n);try{b=null==e.frameElement&&s}catch(A){}b&&b.doScroll&&!function E(){if(!x){try{b.doScroll("left")}catch(e){return i(E,50)}r(),t()}}()}return o.version="1.4.0",o.isReady=function(){return x},o}e.exports="undefined"!=typeof window&&n(window)},function(e,t,n){var r=encodeURIComponent,i=decodeURIComponent,o=n(4),a=n(5),s=/(\w+)\[(\d+)\]/,l=/\w+\.\w+/;t.parse=function(e){if("string"!=typeof e)return{};if(e=o(e),""===e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t={},n=e.split("&"),r=0;r=0;r--)n=e.charCodeAt(r),n>128?t.unshift(["&#",n,";"].join("")):t.unshift(e[r]);return t.join("")},t.imageExists=function(e,t){var n=new Image;n.onerror=function(){t.call(this,!1)},n.onload=function(){t.call(this,!0)},n.src=e},t.decodeHtmlEntity=function(e){return e.replace(/&#(\d+);/g,function(e,t){return String.fromCharCode(t)})},t.dimensionCheck=function(e){var t={height:e.clientHeight,width:e.clientWidth};return!(!t.height||!t.width)&&t},t.truthy=function(e){return"string"==typeof e?"true"===e||"yes"===e||"1"===e||"on"===e||"✓"===e:!!e},t.parseColor=function(e){var t,n=/(^(?:#?)[0-9a-f]{6}$)|(^(?:#?)[0-9a-f]{3}$)/i,r=/^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/,i=/^rgba\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0\.\d{1,}|1)\)$/,o=e.match(n);return null!==o?(t=o[1]||o[2],"#"!==t[0]?"#"+t:t):(o=e.match(r),null!==o?t="rgb("+o.slice(1).join(",")+")":(o=e.match(i),null!==o?t="rgba("+o.slice(1).join(",")+")":null))},t.canvasRatio=function(){var t=1,n=1;if(e.document){var r=e.document.createElement("canvas");if(r.getContext){var i=r.getContext("2d");t=e.devicePixelRatio||1,n=i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1}}return t/n}}).call(t,function(){return this}())},function(e,t,n){(function(e){var r=n(9),i="http://www.w3.org/2000/svg",o=8;t.initSVG=function(e,t,n){var a,s,l=!1;e&&e.querySelector?(s=e.querySelector("style"),null===s&&(l=!0)):(e=r.newEl("svg",i),l=!0),l&&(a=r.newEl("defs",i),s=r.newEl("style",i),r.setAttr(s,{type:"text/css"}),a.appendChild(s),e.appendChild(a)),e.webkitMatchesSelector&&e.setAttribute("xmlns",i);for(var h=0;h=0;l--){var h=s.createProcessingInstruction("xml-stylesheet",'href="'+a[l]+'" rel="stylesheet"');s.insertBefore(h,s.firstChild)}s.removeChild(s.documentElement),o=i.serializeToString(s)}var u=i.serializeToString(t);return u=u.replace(/\&(\#[0-9]{2,}\;)/g,"&$1"),o+u}}}).call(t,function(){return this}())},function(e,t){(function(e){t.newEl=function(t,n){if(e.document)return null==n?e.document.createElement(t):e.document.createElementNS(n,t)},t.setAttr=function(e,t){for(var n in t)e.setAttribute(n,t[n])},t.createXML=function(){if(e.DOMParser)return(new DOMParser).parseFromString("","application/xml")},t.getNodeArray=function(t){var n=null;return"string"==typeof t?n=document.querySelectorAll(t):e.NodeList&&t instanceof e.NodeList?n=t:e.Node&&t instanceof e.Node?n=[t]:e.HTMLCollection&&t instanceof e.HTMLCollection?n=t:t instanceof Array?n=t:null===t&&(n=[]),n=Array.prototype.slice.call(n)}}).call(t,function(){return this}())},function(e,t){var n=function(e,t){"string"==typeof e&&(this.original=e,"#"===e.charAt(0)&&(e=e.slice(1)),/[^a-f0-9]+/i.test(e)||(3===e.length&&(e=e.replace(/./g,"$&$&")),6===e.length&&(this.alpha=1,t&&t.alpha&&(this.alpha=t.alpha),this.set(parseInt(e,16)))))};n.rgb2hex=function(e,t,n){function r(e){var t=(0|e).toString(16);return e<16&&(t="0"+t),t}return[e,t,n].map(r).join("")},n.hsl2rgb=function(e,t,n){var r=e/60,i=(1-Math.abs(2*n-1))*t,o=i*(1-Math.abs(parseInt(r)%2-1)),a=n-i/2,s=0,l=0,h=0;return r>=0&&r<1?(s=i,l=o):r>=1&&r<2?(s=o,l=i):r>=2&&r<3?(l=i,h=o):r>=3&&r<4?(l=o,h=i):r>=4&&r<5?(s=o,h=i):r>=5&&r<6&&(s=i,h=o),s+=a,l+=a,h+=a,s=parseInt(255*s),l=parseInt(255*l),h=parseInt(255*h),[s,l,h]},n.prototype.set=function(e){this.raw=e;var t=(16711680&this.raw)>>16,n=(65280&this.raw)>>8,r=255&this.raw,i=.2126*t+.7152*n+.0722*r,o=-.09991*t-.33609*n+.436*r,a=.615*t-.55861*n-.05639*r;return this.rgb={r:t,g:n,b:r},this.yuv={y:i,u:o,v:a},this},n.prototype.lighten=function(e){var t=Math.min(1,Math.max(0,Math.abs(e)))*(e<0?-1:1),r=255*t|0,i=Math.min(255,Math.max(0,this.rgb.r+r)),o=Math.min(255,Math.max(0,this.rgb.g+r)),a=Math.min(255,Math.max(0,this.rgb.b+r)),s=n.rgb2hex(i,o,a);return new n(s)},n.prototype.toHex=function(e){return(e?"#":"")+this.raw.toString(16)},n.prototype.lighterThan=function(e){return e instanceof n||(e=new n(e)),this.yuv.y>e.yuv.y},n.prototype.blendAlpha=function(e){e instanceof n||(e=new n(e));var t=e,r=this,i=t.alpha*t.rgb.r+(1-t.alpha)*r.rgb.r,o=t.alpha*t.rgb.g+(1-t.alpha)*r.rgb.g,a=t.alpha*t.rgb.b+(1-t.alpha)*r.rgb.b;return new n(n.rgb2hex(i,o,a))},e.exports=n},function(e,t){e.exports={version:"2.9.4",svg_ns:"http://www.w3.org/2000/svg"}},function(e,t,n){function r(e,t){return c.element({tag:t,width:e.width,height:e.height,fill:e.properties.fill})}function i(e){return h.cssProps({fill:e.fill,"font-weight":e.font.weight,"font-family":e.font.family+", monospace","font-size":e.font.size+e.font.units})}function o(e,t,n){var r=n/2;return["M",r,r,"H",e-r,"V",t-r,"H",r,"V",0,"M",0,r,"L",e,t-r,"M",0,t-r,"L",e,r].join(" ")}var a=n(13),s=n(8),l=n(11),h=n(7),u=l.svg_ns,c={element:function(e){var t=e.tag,n=e.content||"";return delete e.tag,delete e.content,[t,n,e]}};e.exports=function(e,t){var n=t.engineSettings,l=n.stylesheets,h=l.map(function(e){return''}).join("\n"),d="holder_"+Number(new Date).toString(16),f=e.root,p=f.children.holderTextGroup,g="#"+d+" text { "+i(p.properties)+" } ";p.y+=.8*p.textPositionData.boundingBox.height;var m=[];Object.keys(p.children).forEach(function(e){var t=p.children[e];Object.keys(t.children).forEach(function(e){var n=t.children[e],r=p.x+t.x+n.x,i=p.y+t.y+n.y,o=c.element({tag:"text",content:n.properties.text,x:r,y:i});m.push(o)})});var v=c.element({tag:"g",content:m}),y=null;if(f.children.holderBg.properties.outline){var w=f.children.holderBg.properties.outline;y=c.element({tag:"path",d:o(f.children.holderBg.width,f.children.holderBg.height,w.width),"stroke-width":w.width,stroke:w.fill,fill:"none"})}var b=r(f.children.holderBg,"rect"),x=[];x.push(b),w&&x.push(y),x.push(v);var S=c.element({tag:"g",id:d,content:x}),A=c.element({tag:"style",content:g,type:"text/css"}),C=c.element({tag:"defs",content:A}),E=c.element({tag:"svg",content:[C,S],width:f.properties.width,height:f.properties.height,xmlns:u,viewBox:[0,0,f.properties.width,f.properties.height].join(" "),preserveAspectRatio:"none"}),k=a(E);k=h+k[0];var T=s.svgStringToDataURI(k,"background"===t.mode);return T}},function(e,t,n){n(14);e.exports=function r(e,t,n){"use strict";function i(e){var t=e.match(/^[\w-]+/),r={tag:t?t[0]:"div",attr:{},children:[]},i=e.match(/#([\w-]+)/),o=e.match(/\$([\w-]+)/),a=e.match(/\.[\w-]+/g);return i&&(r.attr.id=i[1],n[i[1]]=r),o&&(n[o[1]]=r),a&&(r.attr["class"]=a.join(" ").replace(/\./g,"")),e.match(/&$/g)&&(f=!1),r}function o(e,t){if(null!==t&&t!==!1&&void 0!==t)return"string"!=typeof t&&"object"!=typeof t?String(t):t}function a(e){return e||0===e?String(e).replace(/&/g,"&").replace(/"/g,"""):""}function s(e){return String(e).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}var l,h,u,c,d=1,f=!0;if(n=n||{},"string"==typeof e[0])e[0]=i(e[0]);else{if(!Array.isArray(e[0]))throw new Error("First element of array must be a string, or an array and not "+JSON.stringify(e[0]));d=0}for(;d",e[0]=l}return n[0]=e[0],u&&u(e[0]),n}},function(e,t){"use strict";function n(e){var t=""+e,n=r.exec(t);if(!n)return t;var i,o="",a=0,s=0;for(a=n.index;a]/;e.exports=n},function(e,t,n){var r=n(9),i=n(7);e.exports=function(){var e=r.newEl("canvas"),t=null;return function(n){null==t&&(t=e.getContext("2d"));var r=i.canvasRatio(),o=n.root;e.width=r*o.properties.width,e.height=r*o.properties.height,t.textBaseline="middle";var a=o.children.holderBg,s=r*a.width,l=r*a.height,h=2,u=h/2;t.fillStyle=a.properties.fill,t.fillRect(0,0,s,l),a.properties.outline&&(t.strokeStyle=a.properties.outline.fill,t.lineWidth=a.properties.outline.width,t.moveTo(u,u),t.lineTo(s-u,u),t.lineTo(s-u,l-u),t.lineTo(u,l-u),t.lineTo(u,u),t.moveTo(0,u),t.lineTo(s,l-u),t.moveTo(0,l-u),t.lineTo(s,u),t.stroke());var c=o.children.holderTextGroup;t.font=c.properties.font.weight+" "+r*c.properties.font.size+c.properties.font.units+" "+c.properties.font.family+", monospace",t.fillStyle=c.properties.fill;for(var d in c.children){var f=c.children[d];for(var p in f.children){var g=f.children[p],m=r*(c.x+f.x+g.x),v=r*(c.y+f.y+g.y+c.properties.leading/2);t.fillText(g.properties.text,m,v)}}return e.toDataURL("image/png")}}()}])}),function(e,t){t&&(Holder=e.Holder); -}(this,"undefined"!=typeof Meteor&&"undefined"!=typeof Package); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/popper.min.js b/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/popper.min.js deleted file mode 100644 index 79ccbf58b..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/vendor/popper.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - Copyright (C) Federico Zivolo 2018 - Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). - */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=J(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!q(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,y=t(e.instance.popper),w=parseFloat(y['margin'+f],10),E=parseFloat(y['border'+f+'Width'],10),v=b-e.offsets.popper[m]-w-E;return v=$(J(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,Q(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case he.FLIP:p=[n,i];break;case he.CLOCKWISE:p=z(n);break;case he.COUNTERCLOCKWISE:p=z(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,y=-1!==['top','bottom'].indexOf(n),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),w&&(r=G(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!q(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right [class^="col-"] { - padding-right: .75rem; - padding-left: .75rem; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_skiplink.scss b/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_skiplink.scss deleted file mode 100644 index 7ca3074a8..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_skiplink.scss +++ /dev/null @@ -1,14 +0,0 @@ -// stylelint-disable selector-max-id - -#skippy { - display: block; - padding: 1em; - color: #fff; - background-color: $bd-purple; - outline: 0; - - .skiplink-text { - padding: .5em; - outline: 1px dotted; - } -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/.eslintrc.json b/vendor/twbs/bootstrap/site/docs/4.1/examples/.eslintrc.json deleted file mode 100644 index f04fd6ae1..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/.eslintrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "env": { - "es6": false, - "jquery": true - }, - "parserOptions": { - "ecmaVersion": 5, - "sourceType": "script" - }, - "extends": "../../../js/tests/unit/.eslintrc.json" -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/album/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/album/index.html deleted file mode 100644 index b30aea068..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/album/index.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - - Album example for Bootstrap - - - - - - - - - - -
- - -
- -
- -
-
-

Album example

-

Something short and leading about the collection below—its contents, the creator, etc. Make it short and sweet, but not too short so folks don't simply skip over it entirely.

-

- Main call to action - Secondary action -

-
-
- -
-
- -
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
- -
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
- -
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
- Card image cap -
-

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

-
-
- - -
- 9 mins -
-
-
-
-
-
-
- -
- - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/blog/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/blog/index.html deleted file mode 100644 index fef06c476..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/blog/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - Blog Template for Bootstrap - - - - - - - - - - - -
-
-
-
- Subscribe -
-
- -
- -
-
- - - -
-
-

Title of a longer featured blog post

-

Multiple lines of text that form the lede, informing new readers quickly and efficiently about what's most interesting in this post's contents.

-

Continue reading...

-
-
- -
-
-
-
- World -

- Featured post -

-
Nov 12
-

This is a wider card with supporting text below as a natural lead-in to additional content.

- Continue reading -
- Card image cap -
-
-
-
-
- Design -

- Post title -

-
Nov 11
-

This is a wider card with supporting text below as a natural lead-in to additional content.

- Continue reading -
- Card image cap -
-
-
-
- -
-
-
-

- From the Firehose -

- -
-

Sample blog post

- - -

This blog post shows a few different types of content that's supported and styled with Bootstrap. Basic typography, images, and code are all supported.

-
-

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.

-
-

Curabitur blandit tempus porttitor. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit.

-
-

Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.

-

Heading

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.

-

Sub-heading

-

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

-
Example code block
-

Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.

-

Sub-heading

-

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-
    -
  • Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
  • -
  • Donec id elit non mi porta gravida at eget metus.
  • -
  • Nulla vitae elit libero, a pharetra augue.
  • -
-

Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.

-
    -
  1. Vestibulum id ligula porta felis euismod semper.
  2. -
  3. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
  4. -
  5. Maecenas sed diam eget risus varius blandit sit amet non magna.
  6. -
-

Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis.

-
- -
-

Another blog post

- - -

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Sed posuere consectetur est at lobortis. Cras mattis consectetur purus sit amet fermentum.

-
-

Curabitur blandit tempus porttitor. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit.

-
-

Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.

-

Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.

-
- -
-

New feature

- - -

Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-
    -
  • Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
  • -
  • Donec id elit non mi porta gravida at eget metus.
  • -
  • Nulla vitae elit libero, a pharetra augue.
  • -
-

Etiam porta sem malesuada magna mollis euismod. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur.

-

Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.

-
- - - -
- - - -
- -
- - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/carousel/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/carousel/index.html deleted file mode 100644 index bc889dd20..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/carousel/index.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - - - - - Carousel Template for Bootstrap - - - - - - - - - -
- -
- -
- - - - - - - -
- - -
-
- Generic placeholder image -

Heading

-

Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.

-

View details »

-
-
- Generic placeholder image -

Heading

-

Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.

-

View details »

-
-
- Generic placeholder image -

Heading

-

Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-

View details »

-
-
- - - - -
- -
-
-

First featurette heading. It'll blow your mind.

-

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

-
-
- Generic placeholder image -
-
- -
- -
-
-

Oh yeah, it's that good. See for yourself.

-

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

-
-
- Generic placeholder image -
-
- -
- -
-
-

And lastly, this one. Checkmate.

-

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

-
-
- Generic placeholder image -
-
- -
- - - -
- - - - -
- - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/checkout/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/checkout/index.html deleted file mode 100644 index 0dda89ef8..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/checkout/index.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - - - - - Checkout example for Bootstrap - - - - - - - - - - -
-
- -

Checkout form

-

Below is an example form built entirely with Bootstrap's form controls. Each required form group has a validation state that can be triggered by attempting to submit the form without completing it.

-
- -
-
-

- Your cart - 3 -

-
    -
  • -
    -
    Product name
    - Brief description -
    - $12 -
  • -
  • -
    -
    Second product
    - Brief description -
    - $8 -
  • -
  • -
    -
    Third item
    - Brief description -
    - $5 -
  • -
  • -
    -
    Promo code
    - EXAMPLECODE -
    - -$5 -
  • -
  • - Total (USD) - $20 -
  • -
- -
-
- -
- -
-
-
-
-
-

Billing address

-
-
-
- - -
- Valid first name is required. -
-
-
- - -
- Valid last name is required. -
-
-
- -
- -
-
- @ -
- -
- Your username is required. -
-
-
- -
- - -
- Please enter a valid email address for shipping updates. -
-
- -
- - -
- Please enter your shipping address. -
-
- -
- - -
- -
-
- - -
- Please select a valid country. -
-
-
- - -
- Please provide a valid state. -
-
-
- - -
- Zip code required. -
-
-
-
-
- - -
-
- - -
-
- -

Payment

- -
-
- - -
-
- - -
-
- - -
-
-
-
- - - Full name as displayed on card -
- Name on card is required -
-
-
- - -
- Credit card number is required -
-
-
-
-
- - -
- Expiration date required -
-
-
- - -
- Security code required -
-
-
-
- -
-
-
- - -
- - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/cover/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/cover/index.html deleted file mode 100644 index f4281c7cf..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/cover/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - Cover Template for Bootstrap - - - - - - - - - - -
-
-
-

Cover

- -
-
- -
-

Cover your page.

-

Cover is a one-page template for building simple and beautiful home pages. Download, edit the text, and add your own fullscreen background photo to make it your own.

-

- Learn more -

-
- - -
- - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/dashboard/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/dashboard/index.html deleted file mode 100644 index f66c4505d..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/dashboard/index.html +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - - - - Dashboard Template for Bootstrap - - - - - - - - - - - -
-
- - -
-
-

Dashboard

-
-
- - -
- -
-
- - - -

Section title

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#HeaderHeaderHeaderHeader
1,001Loremipsumdolorsit
1,002ametconsecteturadipiscingelit
1,003IntegernecodioPraesent
1,003liberoSedcursusante
1,004dapibusdiamSednisi
1,005Nullaquissemat
1,006nibhelementumimperdietDuis
1,007sagittisipsumPraesentmauris
1,008Fuscenectellussed
1,009auguesemperportaMauris
1,010massaVestibulumlaciniaarcu
1,011egetnullaClassaptent
1,012tacitisociosquadlitora
1,013torquentperconubianostra
1,014perinceptoshimenaeosCurabitur
1,015sodalesligulainlibero
-
-
-
-
- - - - - - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/floating-labels/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/floating-labels/index.html deleted file mode 100644 index 48dc09db1..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/floating-labels/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - Floating labels example for Bootstrap - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/grid.css b/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/grid.css deleted file mode 100644 index 78f5dfda6..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/grid.css +++ /dev/null @@ -1,27 +0,0 @@ -body { - padding-top: 2rem; - padding-bottom: 2rem; -} - -h3 { - margin-top: 2rem; -} - -.row { - margin-bottom: 1rem; -} -.row .row { - margin-top: 1rem; - margin-bottom: 0; -} -[class*="col-"] { - padding-top: 1rem; - padding-bottom: 1rem; - background-color: rgba(86, 61, 124, .15); - border: 1px solid rgba(86, 61, 124, .2); -} - -hr { - margin-top: 2rem; - margin-bottom: 2rem; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/index.html deleted file mode 100644 index 8ef2c72a0..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/grid/index.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - Grid Template for Bootstrap - - - - - - - - - -
- -

Bootstrap grid examples

-

Basic grid layouts to get you familiar with building within the Bootstrap grid system.

- -

Five grid tiers

-

There are five tiers to the Bootstrap grid system, one for each range of devices we support. Each tier starts at a minimum viewport size and automatically applies to the larger devices unless overridden.

- -
-
.col-4
-
.col-4
-
.col-4
-
- -
-
.col-sm-4
-
.col-sm-4
-
.col-sm-4
-
- -
-
.col-md-4
-
.col-md-4
-
.col-md-4
-
- -
-
.col-lg-4
-
.col-lg-4
-
.col-lg-4
-
- -
-
.col-xl-4
-
.col-xl-4
-
.col-xl-4
-
- -

Three equal columns

-

Get three equal-width columns starting at desktops and scaling to large desktops. On mobile devices, tablets and below, the columns will automatically stack.

-
-
.col-md-4
-
.col-md-4
-
.col-md-4
-
- -

Three unequal columns

-

Get three columns starting at desktops and scaling to large desktops of various widths. Remember, grid columns should add up to twelve for a single horizontal block. More than that, and columns start stacking no matter the viewport.

-
-
.col-md-3
-
.col-md-6
-
.col-md-3
-
- -

Two columns

-

Get two columns starting at desktops and scaling to large desktops.

-
-
.col-md-8
-
.col-md-4
-
- -

Full width, single column

-

No grid classes are necessary for full-width elements.

- -
- -

Two columns with two nested columns

-

Per the documentation, nesting is easy—just put a row of columns within an existing column. This gives you two columns starting at desktops and scaling to large desktops, with another two (equal widths) within the larger column.

-

At mobile device sizes, tablets and down, these columns and their nested columns will stack.

-
-
- .col-md-8 -
-
.col-md-6
-
.col-md-6
-
-
-
.col-md-4
-
- -
- -

Mixed: mobile and desktop

-

The Bootstrap v4 grid system has five tiers of classes: xs (extra small), sm (small), md (medium), lg (large), and xl (extra large). You can use nearly any combination of these classes to create more dynamic and flexible layouts.

-

Each tier of classes scales up, meaning if you plan on setting the same widths for xs and sm, you only need to specify xs.

-
-
.col-12 .col-md-8
-
.col-6 .col-md-4
-
-
-
.col-6 .col-md-4
-
.col-6 .col-md-4
-
.col-6 .col-md-4
-
-
-
.col-6
-
.col-6
-
- -
- -

Mixed: mobile, tablet, and desktop

-

-
-
.col-12 .col-sm-6 .col-lg-8
-
.col-6 .col-lg-4
-
-
-
.col-6 .col-sm-4
-
.col-6 .col-sm-4
-
.col-6 .col-sm-4
-
- -
- - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/jumbotron/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/jumbotron/index.html deleted file mode 100644 index 03a2875da..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/jumbotron/index.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - Jumbotron Template for Bootstrap - - - - - - - - - - - - -
- - -
-
-

Hello, world!

-

This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.

-

Learn more »

-
-
- -
- -
-
-

Heading

-

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

-

View details »

-
-
-

Heading

-

Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.

-

View details »

-
-
-

Heading

-

Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-

View details »

-
-
- -
- -
- -
- -
-

© Company 2017-2018

-
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-bottom/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-bottom/index.html deleted file mode 100644 index bc0f63e64..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-bottom/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - Bottom navbar example for Bootstrap - - - - - - -
-
-

Bottom Navbar example

-

This example is a quick exercise to illustrate how the bottom navbar works.

- View navbar docs » -
-
- - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-fixed/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-fixed/index.html deleted file mode 100644 index 10dc37d93..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-fixed/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - Fixed top navbar example for Bootstrap - - - - - - - - - - - - -
-
-

Navbar example

-

This example is a quick exercise to illustrate how fixed to top navbar works. As you scroll, it will remain fixed to the top of your browser's viewport.

- View navbar docs » -
-
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-static/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-static/index.html deleted file mode 100644 index c654bca51..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbar-static/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - Top navbar example for Bootstrap - - - - - - - - - - - - -
-
-

Navbar example

-

This example is a quick exercise to illustrate how the top-aligned navbar works. As you scroll, this navbar remains in its original position and moves with the rest of the page.

- View navbar docs » -
-
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbars/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/navbars/index.html deleted file mode 100644 index 9abe51085..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/navbars/index.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - - - - Navbar Template for Bootstrap - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
-
-
-

Navbar examples

-

This example is a quick exercise to illustrate how the navbar and its contents work. Some navbars extend the width of the viewport, others are confined within a .container. For positioning of navbars, checkout the top and fixed top examples.

-

At the smallest breakpoint, the collapse plugin is used to hide the links and show a menu button to toggle the collapsed content.

-

- View navbar docs » -

-
-
-
-
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/offcanvas/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/offcanvas/index.html deleted file mode 100644 index 7dae17a8a..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/offcanvas/index.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - Offcanvas template for Bootstrap - - - - - - - - - - - - - - -
-
- -
-
Bootstrap
- Since 2011 -
-
- -
-
Recent updates
-
- -

- @username - Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. -

-
-
- -

- @username - Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. -

-
-
- -

- @username - Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. -

-
- - All updates - -
- -
-
Suggestions
-
- -
-
- Full Name - Follow -
- @username -
-
-
- -
-
- Full Name - Follow -
- @username -
-
-
- -
-
- Full Name - Follow -
- @username -
-
- - All suggestions - -
-
- - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/pricing/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/pricing/index.html deleted file mode 100644 index 5ae570aad..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/pricing/index.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - Pricing example for Bootstrap - - - - - - - - - - -
-
Company name
- - Sign up -
- -
-

Pricing

-

Quickly build an effective pricing table for your potential customers with this Bootstrap example. It's built with default Bootstrap components and utilities with little customization.

-
- -
-
-
-
-

Free

-
-
-

$0 / mo

-
    -
  • 10 users included
  • -
  • 2 GB of storage
  • -
  • Email support
  • -
  • Help center access
  • -
- -
-
-
-
-

Pro

-
-
-

$15 / mo

-
    -
  • 20 users included
  • -
  • 10 GB of storage
  • -
  • Priority email support
  • -
  • Help center access
  • -
- -
-
-
-
-

Enterprise

-
-
-

$29 / mo

-
    -
  • 30 users included
  • -
  • 15 GB of storage
  • -
  • Phone and email support
  • -
  • Help center access
  • -
- -
-
-
- - -
- - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/product/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/product/index.html deleted file mode 100644 index 5477eb37b..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/product/index.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - - Product example for Bootstrap - - - - - - - - - - - - -
-
-

Punny headline

-

And an even wittier subheading to boot. Jumpstart your marketing efforts with this example based on Apple's marketing pages.

- Coming soon -
-
-
-
- -
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
- -
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
- -
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
- -
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
-
-

Another headline

-

And an even wittier subheading.

-
-
-
-
- - - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/grid.png b/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/grid.png deleted file mode 100644 index d7a111b0c..000000000 Binary files a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/grid.png and /dev/null differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/sign-in/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/sign-in/index.html deleted file mode 100644 index 2c9436643..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/sign-in/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - Signin Template for Bootstrap - - - - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/starter-template/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/starter-template/index.html deleted file mode 100644 index 03575146d..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/starter-template/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - Starter Template for Bootstrap - - - - - - - - - - - - -
- -
-

Bootstrap starter template

-

Use this document as a way to quickly start any new project.
All you get is this text and a mostly barebones HTML document.

-
- -
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/index.html deleted file mode 100644 index 9f8e174e3..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/index.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - Sticky Footer Navbar Template for Bootstrap - - - - - - - - - - -
- - -
- - -
-

Sticky footer with fixed navbar

-

Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS. A fixed navbar has been added with padding-top: 60px; on the body > .container.

-

Back to the default sticky footer minus the navbar.

-
- -
-
- Place sticky footer content here. -
-
- - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/sticky-footer-navbar.css b/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/sticky-footer-navbar.css deleted file mode 100644 index 07fd56a64..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer-navbar/sticky-footer-navbar.css +++ /dev/null @@ -1,37 +0,0 @@ -/* Sticky footer styles --------------------------------------------------- */ -html { - position: relative; - min-height: 100%; -} -body { - /* Margin bottom by footer height */ - margin-bottom: 60px; -} -.footer { - position: absolute; - bottom: 0; - width: 100%; - /* Set the fixed height of the footer here */ - height: 60px; - line-height: 60px; /* Vertically center the text there */ - background-color: #f5f5f5; -} - - -/* Custom page CSS --------------------------------------------------- */ -/* Not required for template or sticky footer method. */ - -body > .container { - padding: 60px 15px 0; -} - -.footer > .container { - padding-right: 15px; - padding-left: 15px; -} - -code { - font-size: 80%; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/index.html deleted file mode 100644 index 839d9883e..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - Sticky Footer Template for Bootstrap - - - - - - - - - - - -
-

Sticky footer

-

Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS.

-

Use the sticky footer with a fixed navbar if need be, too.

-
- -
-
- Place sticky footer content here. -
-
- - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/sticky-footer.css b/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/sticky-footer.css deleted file mode 100644 index ebe29104f..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/sticky-footer/sticky-footer.css +++ /dev/null @@ -1,28 +0,0 @@ -/* Sticky footer styles --------------------------------------------------- */ -html { - position: relative; - min-height: 100%; -} -body { - margin-bottom: 60px; /* Margin bottom by footer height */ -} -.footer { - position: absolute; - bottom: 0; - width: 100%; - height: 60px; /* Set the fixed height of the footer here */ - line-height: 60px; /* Vertically center the text there */ - background-color: #f5f5f5; -} - - -/* Custom page CSS --------------------------------------------------- */ -/* Not required for template or sticky footer method. */ - -.container { - width: auto; - max-width: 680px; - padding: 0 15px; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/index.html b/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/index.html deleted file mode 100644 index fabe12ddf..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - Tooltip Viewport Example for Bootstrap - - - - - - - - - - - - - - - - -
- - - - - - -
- - - - - - - - - - diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.css b/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.css deleted file mode 100644 index 26aa2e348..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.css +++ /dev/null @@ -1,26 +0,0 @@ -body { - height: 1200px; -} -.tooltip { - min-width: 250px; - max-width: 500px; -} -.tooltip .tooltip-inner { - min-width: 250px; - max-width: 500px; - min-height: 100px; - text-align: left; -} -.container-viewport { - position: absolute; - top: 100px; - right: 250px; - left: 250px; - height: 300px; - background-color: #eee; -} -.btn-bottom { - position: absolute; - bottom: 0; - left: 0; -} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.js b/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.js deleted file mode 100644 index dc75e18c6..000000000 --- a/vendor/twbs/bootstrap/site/docs/4.1/examples/tooltip-viewport/tooltip-viewport.js +++ /dev/null @@ -1,32 +0,0 @@ -$(function () { - 'use strict' - - $('.tooltip-right').tooltip({ - placement: 'right', - viewport: { - selector: 'body', - padding: 2 - } - }) - $('.tooltip-bottom').tooltip({ - placement: 'bottom', - viewport: { - selector: 'body', - padding: 2 - } - }) - $('.tooltip-viewport-right').tooltip({ - placement: 'right', - viewport: { - selector: '.container-viewport', - padding: 2 - } - }) - $('.tooltip-viewport-bottom').tooltip({ - placement: 'bottom', - viewport: { - selector: '.container-viewport', - padding: 2 - } - }) -}) diff --git a/vendor/twbs/bootstrap/site/docs/4.1/about/brand.md b/vendor/twbs/bootstrap/site/docs/4.3/about/brand.md similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/about/brand.md rename to vendor/twbs/bootstrap/site/docs/4.3/about/brand.md diff --git a/vendor/twbs/bootstrap/site/docs/4.1/about/license.md b/vendor/twbs/bootstrap/site/docs/4.3/about/license.md similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/about/license.md rename to vendor/twbs/bootstrap/site/docs/4.3/about/license.md diff --git a/vendor/twbs/bootstrap/site/docs/4.1/about/overview.md b/vendor/twbs/bootstrap/site/docs/4.3/about/overview.md similarity index 84% rename from vendor/twbs/bootstrap/site/docs/4.1/about/overview.md rename to vendor/twbs/bootstrap/site/docs/4.3/about/overview.md index 23dd7affe..f3460baa1 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/about/overview.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/about/overview.md @@ -2,11 +2,10 @@ layout: docs title: About description: Learn more about the team maintaining Bootstrap, how and why the project started, and how to get involved. -redirect_from: - - "/docs/4.1/about/" - - "/docs/4.1/history/" - - "/docs/4.1/team/" group: about +redirect_from: + - "/about/" + - "/docs/4.3/about/" --- ## Team @@ -17,7 +16,7 @@ Bootstrap is maintained by a [small team of developers](https://github.com/orgs/ Originally created by a designer and a developer at Twitter, Bootstrap has become one of the most popular front-end frameworks and open source projects in the world. -Bootstrap was created at Twitter in mid-2010 by [@mdo](https://twitter.com/mdo) and [@fat](https://twitter.com/fat). Prior to being an open-sourced framework, Bootstrap was known as _Twitter Blueprint_. A few months into development, Twitter held its [first Hack Week](https://blog.twitter.com/2010/hack-week) and the project exploded as developers of all skill levels jumped in without any external guidance. It served as the style guide for internal tools development at the company for over a year before its public release, and continues to do so today. +Bootstrap was created at Twitter in mid-2010 by [@mdo](https://twitter.com/mdo) and [@fat](https://twitter.com/fat). Prior to being an open-sourced framework, Bootstrap was known as _Twitter Blueprint_. A few months into development, Twitter held its [first Hack Week](https://blog.twitter.com/engineering/en_us/a/2010/hack-week.html) and the project exploded as developers of all skill levels jumped in without any external guidance. It served as the style guide for internal tools development at the company for over a year before its public release, and continues to do so today. Originally [released](https://blog.twitter.com/developer/en_us/a/2011/bootstrap-twitter.html) on , we've since had over [twenty releases]({{ site.repo }}/releases), including two major rewrites with v2 and v3. With Bootstrap 2, we added responsive functionality to the entire framework as an optional stylesheet. Building on that with Bootstrap 3, we rewrote the library once more to make it responsive by default with a mobile first approach. diff --git a/vendor/twbs/bootstrap/site/docs/4.3/about/team.md b/vendor/twbs/bootstrap/site/docs/4.3/about/team.md new file mode 100644 index 000000000..93aecf882 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/about/team.md @@ -0,0 +1,21 @@ +--- +layout: docs +title: Team +description: An overview of the founding team and core contributors to Bootstrap. +group: about +--- + +Bootstrap is maintained by the founding team and a small group of invaluable core contributors, with the massive support and involvement of our community. + +
+ {% for member in site.data.core-team %} + + @{{ member.user }} + + {{ member.name }} @{{ member.user }} + + + {% endfor %} +
+ +Get involved with Bootstrap development by [opening an issue]({{ site.repo }}/issues/new) or submitting a pull request. Read our [contributing guidelines]({{ site.repo }}/blob/v{{ site.current_version }}/.github/CONTRIBUTING.md) for information on how we develop. diff --git a/vendor/twbs/bootstrap/site/docs/4.1/about/translations.md b/vendor/twbs/bootstrap/site/docs/4.3/about/translations.md similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/about/translations.md rename to vendor/twbs/bootstrap/site/docs/4.3/about/translations.md diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-outline.svg b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-outline.svg similarity index 86% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-outline.svg rename to vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-outline.svg index 215be0585..6e136ca87 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-outline.svg +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-outline.svg @@ -1,4 +1,5 @@ - + + Bootstrap diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-punchout.svg b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-punchout.svg similarity index 83% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-punchout.svg rename to vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-punchout.svg index 9f4f529cc..81c20b0d8 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-punchout.svg +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-punchout.svg @@ -1,4 +1,5 @@ - + + Bootstrap diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-social-logo.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-social-logo.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-social-logo.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-social-logo.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-social.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-social.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-social.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-social.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-solid.svg b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-solid.svg similarity index 84% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-solid.svg rename to vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-solid.svg index 5d860a70e..4eed29bb7 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/brand/bootstrap-solid.svg +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/brand/bootstrap-solid.svg @@ -1,4 +1,5 @@ - + + Bootstrap diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css b/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css new file mode 100644 index 000000000..72d169366 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css @@ -0,0 +1,8 @@ +/*! + * Bootstrap Docs (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the Creative Commons Attribution 3.0 Unported License. + * For details, see https://creativecommons.org/licenses/by/3.0/. + */.bd-navbar{min-height:4rem;background-color:#563d7c;box-shadow:0 .5rem 1rem rgba(0,0,0,.05),inset 0 -1px 0 rgba(0,0,0,.1)}@media (max-width:991.98px){.bd-navbar{padding-right:.5rem;padding-left:.5rem}.bd-navbar .navbar-nav-scroll{max-width:100%;height:2.5rem;margin-top:.25rem;overflow:hidden}.bd-navbar .navbar-nav-scroll .navbar-nav{padding-bottom:2rem;overflow-x:auto;white-space:nowrap;-webkit-overflow-scrolling:touch}}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-navbar{position:-webkit-sticky;position:sticky;top:0;z-index:1071}}}.bd-navbar .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem;color:#cbbde2}.bd-navbar .navbar-nav .nav-link.active,.bd-navbar .navbar-nav .nav-link:hover{color:#fff;background-color:transparent}.bd-navbar .navbar-nav .nav-link.active{font-weight:600}.bd-navbar .navbar-nav-svg{display:inline-block;width:1rem;height:1rem;vertical-align:text-top}.bd-navbar .dropdown-menu{font-size:.875rem}.bd-navbar .dropdown-item.active{font-weight:600;color:#212529;background-color:transparent;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:.4rem .6rem;background-size:.75rem .75rem}.bd-masthead{position:relative;padding:3rem 15px}.bd-masthead h1{font-size:4rem;line-height:1}@media (max-width:1200px){.bd-masthead h1{font-size:calc(1.525rem + 3.3vw)}}.bd-masthead .btn{padding:.8rem 2rem;font-weight:600;font-size:1.25rem}.bd-masthead .carbonad{margin-top:0!important;margin-bottom:-3rem!important}@media (min-width:576px){.bd-masthead{padding-top:5rem;padding-bottom:5rem}.bd-masthead .carbonad{margin-bottom:0!important}}@media (min-width:768px){.bd-masthead .carbonad{margin-top:3rem!important}}.half-rule{width:6rem;margin:2.5rem 0}.masthead-followup .bd-clipboard{display:none}.masthead-followup .highlight{padding:.5rem 0;background-color:transparent}#carbonads{position:static;display:block;max-width:400px;padding:15px 15px 15px 160px;margin:2rem 0;overflow:hidden;font-size:.8125rem;line-height:1.4;text-align:left;background-color:rgba(0,0,0,.05)}#carbonads a{color:#333;text-decoration:none}@media (min-width:576px){#carbonads{max-width:330px;border-radius:4px}}.carbon-img{float:left;margin-left:-145px}.carbon-poweredby{display:block;color:#777!important}.bd-content{-ms-flex-order:1;order:1}.bd-content>h2[id],.bd-content>h3[id],.bd-content>h4[id]{pointer-events:none}.bd-content>h2[id]::before,.bd-content>h3[id]::before,.bd-content>h4[id]::before{display:block;height:6rem;margin-top:-6rem;content:""}.bd-content>table{width:100%;max-width:100%;margin-bottom:1rem}@media (max-width:991.98px){.bd-content>table{display:block;overflow-x:auto}.bd-content>table.table-bordered{border:0}}.bd-content>table>tbody>tr>td,.bd-content>table>tbody>tr>th,.bd-content>table>tfoot>tr>td,.bd-content>table>tfoot>tr>th,.bd-content>table>thead>tr>td,.bd-content>table>thead>tr>th{padding:.75rem;vertical-align:top;border:1px solid #dee2e6}.bd-content>table>tbody>tr>td>p:last-child,.bd-content>table>tbody>tr>th>p:last-child,.bd-content>table>tfoot>tr>td>p:last-child,.bd-content>table>tfoot>tr>th>p:last-child,.bd-content>table>thead>tr>td>p:last-child,.bd-content>table>thead>tr>th>p:last-child{margin-bottom:0}.bd-content>table td:first-child>code{white-space:nowrap}.bd-content-title{display:block;pointer-events:auto}.bd-content>h2{font-size:2rem}@media (max-width:1200px){.bd-content>h2{font-size:calc(1.325rem + .9vw)}}.bd-content>h3{font-size:1.75rem}@media (max-width:1200px){.bd-content>h3{font-size:calc(1.3rem + .6vw)}}.bd-content>h4{font-size:1.5rem}@media (max-width:1200px){.bd-content>h4{font-size:calc(1.275rem + .3vw)}}.bd-content>h2:not(:first-child){margin-top:3rem}.bd-content>h3{margin-top:1.5rem}.bd-content>ol li,.bd-content>ul li{margin-bottom:.25rem}@media (min-width:992px){.bd-content>ol,.bd-content>p,.bd-content>ul{max-width:80%}}.bd-title{margin-top:1rem;margin-bottom:.5rem;font-weight:300;font-size:3rem}@media (max-width:1200px){.bd-title{font-size:calc(1.425rem + 2.1vw)}}.bd-lead{font-size:1.5rem;font-weight:300}@media (max-width:1200px){.bd-lead{font-size:calc(1.275rem + .3vw)}}@media (min-width:992px){.bd-lead{max-width:80%}}.bd-text-purple{color:#563d7c}.bd-text-purple-bright{color:#7952b3}.skippy{display:block;padding:1em;color:#fff;text-align:center;background-color:#563d7c;outline:0}.skippy:hover{color:#fff}.skippy-text{padding:.5em;outline:1px dotted}.bd-toc{-ms-flex-order:2;order:2;padding-top:1.5rem;padding-bottom:1.5rem;font-size:.875rem}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-toc{position:-webkit-sticky;position:sticky;top:4rem;height:calc(100vh - 4rem);overflow-y:auto}}.section-nav{padding-left:0;border-left:1px solid #eee}.section-nav ul{padding-left:1rem}.toc-entry{display:block}.toc-entry a{display:block;padding:.125rem 1.5rem;color:#77757a}.toc-entry a:hover{color:#007bff;text-decoration:none}.bd-sidebar{-ms-flex-order:0;order:0;border-bottom:1px solid rgba(0,0,0,.1)}@media (min-width:768px){.bd-sidebar{border-right:1px solid rgba(0,0,0,.1)}@supports ((position:-webkit-sticky) or (position:sticky)){.bd-sidebar{position:-webkit-sticky;position:sticky;top:4rem;z-index:1000;height:calc(100vh - 4rem)}}}@media (min-width:1200px){.bd-sidebar{-ms-flex:0 1 320px;flex:0 1 320px}}.bd-links{padding-top:1rem;padding-bottom:1rem;margin-right:-15px;margin-left:-15px}@media (min-width:768px){@supports ((position:-webkit-sticky) or (position:sticky)){.bd-links{max-height:calc(100vh - 9rem);overflow-y:auto}}}@media (min-width:768px){.bd-links{display:block!important}}.bd-search{position:relative;padding:1rem 15px;margin-right:-15px;margin-left:-15px;border-bottom:1px solid rgba(0,0,0,.05)}.bd-search .form-control:focus{border-color:#7952b3;box-shadow:0 0 0 3px rgba(121,82,179,.25)}.bd-search-docs-toggle{line-height:1;color:#212529}.bd-sidenav{display:none}.bd-toc-link{display:block;padding:.25rem 1.5rem;font-weight:600;color:rgba(0,0,0,.65)}.bd-toc-link:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-toc-item.active{margin-bottom:1rem}.bd-toc-item.active:not(:first-child){margin-top:1rem}.bd-toc-item.active>.bd-toc-link{color:rgba(0,0,0,.85)}.bd-toc-item.active>.bd-toc-link:hover{background-color:transparent}.bd-toc-item.active>.bd-sidenav{display:block}.bd-sidebar .nav>li>a{display:block;padding:.25rem 1.5rem;font-size:90%;color:rgba(0,0,0,.65)}.bd-sidebar .nav>li>a:hover{color:rgba(0,0,0,.85);text-decoration:none;background-color:transparent}.bd-sidebar .nav>.active:hover>a,.bd-sidebar .nav>.active>a{font-weight:600;color:rgba(0,0,0,.85);background-color:transparent}.bd-footer{font-size:.875rem;text-align:center;background-color:#f7f7f7}.bd-footer a{font-weight:600;color:#495057}.bd-footer a:focus,.bd-footer a:hover{color:#007bff}.bd-footer p{margin-bottom:0}@media (min-width:576px){.bd-footer{text-align:left}}.bd-footer-links{padding-left:0;margin-bottom:1rem}.bd-footer-links li{display:inline-block}.bd-footer-links li+li{margin-left:1rem}.bd-example-row .row>.col,.bd-example-row .row>[class^=col-]{padding-top:.75rem;padding-bottom:.75rem;background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.2)}.bd-example-row .row+.row{margin-top:1rem}.bd-example-row .flex-items-bottom,.bd-example-row .flex-items-middle,.bd-example-row .flex-items-top{min-height:6rem;background-color:rgba(255,0,0,.1)}.bd-example-row-flex-cols .row{min-height:10rem;background-color:rgba(255,0,0,.1)}.bd-highlight{background-color:rgba(86,61,124,.15);border:1px solid rgba(86,61,124,.15)}.example-container{width:800px;width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.example-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.example-content-main{position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-main{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-main{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}}.example-content-secondary{position:relative;width:100%;padding-right:15px;padding-left:15px}@media (min-width:576px){.example-content-secondary{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}}@media (min-width:992px){.example-content-secondary{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}}.bd-example-container{min-width:16rem;max-width:25rem;margin-right:auto;margin-left:auto}.bd-example-container-header{height:3rem;margin-bottom:.5rem;background-color:#fff;border-radius:.25rem}.bd-example-container-sidebar{float:right;width:4rem;height:8rem;background-color:#80bdff;border-radius:.25rem}.bd-example-container-body{height:8rem;margin-right:4.5rem;background-color:#957bbe;border-radius:.25rem}.bd-example-container-fluid{max-width:none}.bd-example{position:relative;padding:1rem;margin:1rem -15px 0;border:solid #f8f9fa;border-width:.2rem 0 0}.bd-example::after{display:block;clear:both;content:""}@media (min-width:576px){.bd-example{padding:1.5rem;margin-right:0;margin-left:0;border-width:.2rem}}.bd-example+.clipboard+.highlight,.bd-example+.highlight{margin-top:0}.bd-example+p{margin-top:2rem}.bd-example .pos-f-t{position:relative;margin:-1rem}@media (min-width:576px){.bd-example .pos-f-t{margin:-1.5rem}}.bd-example .custom-file-input:lang(es)~.custom-file-label::after{content:"Elegir"}.bd-example>.form-control+.form-control{margin-top:.5rem}.bd-example>.alert+.alert,.bd-example>.nav+.nav,.bd-example>.navbar+.navbar,.bd-example>.progress+.btn,.bd-example>.progress+.progress{margin-top:1rem}.bd-example>.dropdown-menu:first-child{position:static;display:block}.bd-example>.form-group:last-child{margin-bottom:0}.bd-example>.close{float:none}.bd-example-type .table td{padding:1rem 0;border-color:#eee}.bd-example-type .table tr:first-child td{border-top:0}.bd-example-type h1,.bd-example-type h2,.bd-example-type h3,.bd-example-type h4,.bd-example-type h5,.bd-example-type h6{margin-top:0;margin-bottom:0}.bd-example-bg-classes p{padding:1rem}.bd-example>img+img,.bd-example>svg+svg{margin-left:.5rem}.bd-example>.btn,.bd-example>.btn-group{margin-top:.25rem;margin-bottom:.25rem}.bd-example>.btn-toolbar+.btn-toolbar{margin-top:.5rem}.bd-example-control-sizing input[type=text]+input[type=text],.bd-example-control-sizing select{margin-top:.5rem}.bd-example-form .input-group{margin-bottom:.5rem}.bd-example>textarea.form-control{resize:vertical}.bd-example>.list-group{max-width:400px}.bd-example>[class*=list-group-horizontal]{max-width:100%}.bd-example .fixed-top,.bd-example .sticky-top{position:static;margin:-1rem -1rem 1rem}.bd-example .fixed-bottom{position:static;margin:1rem -1rem -1rem}@media (min-width:576px){.bd-example .fixed-top,.bd-example .sticky-top{margin:-1.5rem -1.5rem 1rem}.bd-example .fixed-bottom{margin:1rem -1.5rem -1.5rem}}.bd-example .pagination{margin-top:.5rem;margin-bottom:.5rem}.modal{z-index:1072}.modal .popover,.modal .tooltip{z-index:1073}.modal-backdrop{z-index:1071}.bd-example-modal{background-color:#fafafa}.bd-example-modal .modal{position:relative;top:auto;right:auto;bottom:auto;left:auto;z-index:1;display:block}.bd-example-modal .modal-dialog{left:auto;margin-right:auto;margin-left:auto}.bd-example-tabs .nav-tabs{margin-bottom:1rem}.bd-example-popover-static{padding-bottom:1.5rem;background-color:#f9f9f9}.bd-example-popover-static .popover{position:relative;display:block;float:left;width:260px;margin:1.25rem}.tooltip-demo a{white-space:nowrap}.bd-example-tooltip-static .tooltip{position:relative;display:inline-block;margin:10px 20px;opacity:1}.scrollspy-example{position:relative;height:200px;margin-top:.5rem;overflow:auto}.scrollspy-example-2{position:relative;height:350px;overflow:auto}.bd-example-border-utils [class^=border]{display:inline-block;width:5rem;height:5rem;margin:.25rem;background-color:#f5f5f5}.bd-example-border-utils-0 [class^=border]{border:1px solid #dee2e6}.highlight{padding:1rem;margin-top:1rem;margin-bottom:1rem;background-color:#f8f9fa;-ms-overflow-style:-ms-autohiding-scrollbar}@media (min-width:576px){.highlight{padding:1.5rem}}.bd-content .highlight{margin-right:-15px;margin-left:-15px}@media (min-width:576px){.bd-content .highlight{margin-right:0;margin-left:0}}.highlight pre{padding:0;margin-top:0;margin-bottom:0;background-color:transparent;border:0}.highlight pre code{font-size:inherit;color:#212529}.btn-bd-primary{font-weight:600;color:#7952b3;border-color:#7952b3}.btn-bd-primary:active,.btn-bd-primary:hover{color:#fff;background-color:#7952b3;border-color:#7952b3}.btn-bd-primary:focus{box-shadow:0 0 0 3px rgba(121,82,179,.25)}.btn-bd-download{font-weight:600;color:#ffe484;border-color:#ffe484}.btn-bd-download:active,.btn-bd-download:hover{color:#2a2730;background-color:#ffe484;border-color:#ffe484}.btn-bd-download:focus{box-shadow:0 0 0 3px rgba(255,228,132,.25)}.bd-callout{padding:1.25rem;margin-top:1.25rem;margin-bottom:1.25rem;border:1px solid #eee;border-left-width:.25rem;border-radius:.25rem}.bd-callout h4{margin-top:0;margin-bottom:.25rem}.bd-callout p:last-child{margin-bottom:0}.bd-callout code{border-radius:.25rem}.bd-callout+.bd-callout{margin-top:-.25rem}.bd-callout-info{border-left-color:#5bc0de}.bd-callout-info h4{color:#5bc0de}.bd-callout-warning{border-left-color:#f0ad4e}.bd-callout-warning h4{color:#f0ad4e}.bd-callout-danger{border-left-color:#d9534f}.bd-callout-danger h4{color:#d9534f}.bd-browser-bugs td p{margin-bottom:0}.bd-browser-bugs th:first-child{width:18%}.bd-brand-logos{display:table;width:100%;margin-bottom:1rem;overflow:hidden;color:#563d7c;background-color:#f9f9f9;border-radius:.25rem}.bd-brand-logos .inverse{color:#fff;background-color:#563d7c}.bd-brand-item{padding:4rem 0;text-align:center}.bd-brand-item+.bd-brand-item{border-top:1px solid #fff}.bd-brand-item h1,.bd-brand-item h3{margin-top:0;margin-bottom:0}@media (min-width:768px){.bd-brand-item{display:table-cell;width:1%}.bd-brand-item+.bd-brand-item{border-top:0;border-left:1px solid #fff}.bd-brand-item h1{font-size:4rem}}@media (min-width:768px) and (max-width:1200px){.bd-brand-item h1{font-size:calc(1.525rem + 3.3vw)}}.color-swatches{margin:0 -5px;overflow:hidden}.color-swatches .bd-purple{background-color:#563d7c}.color-swatches .bd-purple-light{background-color:#cbbde2}.color-swatches .bd-purple-lighter{background-color:#e5e1ea}.color-swatches .bd-gray{background-color:#f9f9f9}.color-swatch{float:left;width:4rem;height:4rem;margin-right:.25rem;margin-left:.25rem;border-radius:.25rem}@media (min-width:768px){.color-swatch{width:6rem;height:6rem}}.swatch-blue{color:#fff;background-color:#007bff}.swatch-indigo{color:#fff;background-color:#6610f2}.swatch-purple{color:#fff;background-color:#6f42c1}.swatch-pink{color:#fff;background-color:#e83e8c}.swatch-red{color:#fff;background-color:#dc3545}.swatch-orange{color:#212529;background-color:#fd7e14}.swatch-yellow{color:#212529;background-color:#ffc107}.swatch-green{color:#fff;background-color:#28a745}.swatch-teal{color:#fff;background-color:#20c997}.swatch-cyan{color:#fff;background-color:#17a2b8}.swatch-white{color:#212529;background-color:#fff}.swatch-gray{color:#fff;background-color:#6c757d}.swatch-gray-dark{color:#fff;background-color:#343a40}.swatch-primary{color:#fff;background-color:#007bff}.swatch-secondary{color:#fff;background-color:#6c757d}.swatch-success{color:#fff;background-color:#28a745}.swatch-info{color:#fff;background-color:#17a2b8}.swatch-warning{color:#212529;background-color:#ffc107}.swatch-danger{color:#fff;background-color:#dc3545}.swatch-light{color:#212529;background-color:#f8f9fa}.swatch-dark{color:#fff;background-color:#343a40}.swatch-100{color:#212529;background-color:#f8f9fa}.swatch-200{color:#212529;background-color:#e9ecef}.swatch-300{color:#212529;background-color:#dee2e6}.swatch-400{color:#212529;background-color:#ced4da}.swatch-500{color:#212529;background-color:#adb5bd}.swatch-600{color:#fff;background-color:#6c757d}.swatch-700{color:#fff;background-color:#495057}.swatch-800{color:#fff;background-color:#343a40}.swatch-900{color:#fff;background-color:#212529}.bd-clipboard{position:relative;display:none;float:right}.bd-clipboard+.highlight{margin-top:0}@media (min-width:768px){.bd-clipboard{display:block}}.btn-clipboard{position:absolute;top:.5rem;right:.5rem;z-index:10;display:block;padding:.25rem .5rem;font-size:75%;color:#818a91;background-color:transparent;border:0;border-radius:.25rem}.btn-clipboard:hover{color:#fff;background-color:#027de7}.bd-placeholder-img{font-size:1.125rem;text-anchor:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bd-placeholder-img-lg{font-size:3.5rem}@media (max-width:1200px){.bd-placeholder-img-lg{font-size:calc(1.475rem + 2.7vw)}}.hll{background-color:#ffc}.c{color:#999}.k{color:#069}.o{color:#555}.cm{color:#999}.cp{color:#099}.c1{color:#999}.cs{color:#999}.gd{background-color:#fcc;border:1px solid #c00}.ge{font-style:italic}.gr{color:red}.gh{color:#030}.gi{background-color:#cfc;border:1px solid #0c0}.go{color:#aaa}.gp{color:#009}.gu{color:#030}.gt{color:#9c6}.kc{color:#069}.kd{color:#069}.kn{color:#069}.kp{color:#069}.kr{color:#069}.kt{color:#078}.m{color:#f60}.s{color:#d44950}.na{color:#4f9fcf}.nb{color:#366}.nc{color:#0a8}.no{color:#360}.nd{color:#99f}.ni{color:#999}.ne{color:#c00}.nf{color:#c0f}.nl{color:#99f}.nn{color:#0cf}.nt{color:#2f6f9f}.nv{color:#033}.ow{color:#000}.w{color:#bbb}.mf{color:#f60}.mh{color:#f60}.mi{color:#f60}.mo{color:#f60}.sb{color:#c30}.sc{color:#c30}.sd{font-style:italic;color:#c30}.s2{color:#c30}.se{color:#c30}.sh{color:#c30}.si{color:#a00}.sx{color:#c30}.sr{color:#3aa}.s1{color:#c30}.ss{color:#fc3}.bp{color:#366}.vc{color:#033}.vg{color:#033}.vi{color:#033}.il{color:#f60}.css .nt+.nt,.css .o,.css .o+.nt{color:#999}.language-bash::before,.language-sh::before{color:#009;content:"$ ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.language-powershell::before{color:#009;content:"PM> ";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.anchorjs-link{font-weight:400;color:rgba(0,123,255,.5);transition:color .15s ease-in-out,opacity .15s ease-in-out}@media (prefers-reduced-motion:reduce){.anchorjs-link{transition:none}}.anchorjs-link:hover{color:#007bff;text-decoration:none}.algolia-autocomplete{display:block!important;-ms-flex:1;flex:1}.algolia-autocomplete .ds-dropdown-menu{width:100%;min-width:0!important;max-width:none!important;padding:.75rem 0!important;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.175)}@media (min-width:768px){.algolia-autocomplete .ds-dropdown-menu{width:175%}}.algolia-autocomplete .ds-dropdown-menu::before{display:none!important}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{padding:0!important;overflow:visible!important;background-color:transparent!important;border:0!important}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion{padding:0!important;overflow:visible!important}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{padding:.125rem 1rem!important;margin-top:0!important;font-size:.875rem!important;font-weight:600!important;color:#7952b3!important;border-bottom:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{float:none!important;padding-top:0!important}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:none!important;width:auto!important;padding:0!important;text-align:left!important}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:block!important;font-size:.875rem;color:#495057}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline::after{padding:0 .25rem;content:"/"}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;float:none!important;width:100%!important;padding:.25rem 1rem!important}.algolia-autocomplete .algolia-docsearch-suggestion--content::before{display:none!important}.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header{padding-top:.75rem!important;margin-top:.75rem!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column{display:none!important}.algolia-autocomplete .algolia-docsearch-suggestion--title{display:block;margin-bottom:0!important;font-size:.875rem!important;font-weight:400!important}.algolia-autocomplete .algolia-docsearch-suggestion--text{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%;padding:.2rem 0;font-size:.8125rem!important;font-weight:400;line-height:1.25!important;color:#6c757d}.algolia-autocomplete .algolia-docsearch-footer{float:none!important;width:auto!important;height:auto!important;padding:.75rem 1rem 0;font-size:.75rem!important;line-height:1!important;color:#767676!important;border-top:1px solid rgba(0,0,0,.1)}.algolia-autocomplete .algolia-docsearch-footer--logo{display:inline!important;overflow:visible!important;color:inherit!important;text-indent:0!important;background:0 0!important}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#5f2dab;background-color:rgba(154,132,187,.12)}.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{box-shadow:inset 0 -2px 0 0 rgba(95,45,171,.5)!important}.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content{background-color:rgba(208,189,236,.15)!important} +/*# sourceMappingURL=docs.min.css.map */ \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css.map b/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css.map new file mode 100644 index 000000000..6fa620fe4 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/css/docs.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../scss/docs.scss","../scss/_nav.scss","../../../../../scss/mixins/_breakpoints.scss","../../../../../scss/vendor/_rfs.scss","../scss/_masthead.scss","../scss/_ads.scss","../../../../../scss/mixins/_border-radius.scss","../scss/_content.scss","site/docs/4.3/assets/css/docs.min.css","../scss/_skippy.scss","../../../../../scss/mixins/_hover.scss","../scss/_sidebar.scss","../scss/_footer.scss","../scss/_component-examples.scss","../../../../../scss/mixins/_grid.scss","../../../../../scss/mixins/_clearfix.scss","../scss/_buttons.scss","../scss/_callouts.scss","../scss/_browser-bugs.scss","../scss/_brand.scss","../scss/_colors.scss","../scss/_clipboard-js.scss","../scss/_placeholder-img.scss","../scss/_syntax.scss","../scss/_anchor.scss","../../../../../scss/mixins/_transition.scss","../scss/_algolia.scss"],"names":[],"mappings":"AAAA;;;;;;ACIA,WACE,WAAA,KACA,iBAAA,QACA,WAAA,EAAA,MAAA,KAAA,eAAA,CAAA,MAAA,EAAA,KAAA,EAAA,eCkEE,4BDrEJ,WAMI,cAAA,MACA,aAAA,MAPJ,8BAUM,UAAA,KACA,OAAA,OACA,WAAA,OACA,SAAA,OAbN,0CAgBQ,eAAA,KACA,WAAA,KACA,YAAA,OACA,2BAAA,OCqCJ,yBD/B4B,2DAzBhC,WA0BM,SAAA,eAAA,SAAA,OACA,IAAA,EACA,QAAA,OA5BN,iCAkCM,cAAA,MACA,aAAA,MACA,MAAA,QApCN,wCAAA,uCAwCQ,MAAA,KACA,iBAAA,YAzCR,wCA6CQ,YAAA,IA7CR,2BAmDI,QAAA,aACA,MAAA,KACA,OAAA,KACA,eAAA,SAtDJ,0BE2HM,UAAA,QF3HN,iCA8DI,YAAA,IACA,MAAA,QACA,iBAAA,YACA,iBAAA,2OACA,kBAAA,UACA,oBAAA,MAAA,MACA,gBAAA,OAAA,OGtEJ,aACE,SAAA,SACA,QAAA,KAAA,KAFF,gBDuJQ,UAAA,KChJJ,YAAA,EDsKI,0BC7KR,gBDqLY,UAAA,wBCrLZ,kBAWI,QAAA,MAAA,KACA,YAAA,IDiHE,UAAA,QC7HN,uBAiBI,WAAA,YACA,cAAA,gBFwCA,yBE1DJ,aAsBI,YAAA,KACA,eAAA,KAvBJ,uBA0BM,cAAA,aFgCF,yBE1DJ,uBAgCM,WAAA,gBAKN,WACE,MAAA,KACA,OAAA,OAAA,EAGF,iCACkB,QAAA,KADlB,8BAII,QAAA,MAAA,EACA,iBAAA,YC3CJ,WACE,SAAA,OACA,QAAA,MACA,UAAA,MACA,QAAA,KAAA,KAAA,KAAA,MACA,OAAA,KAAA,EACA,SAAA,OFmHI,UAAA,SEjHJ,YAAA,IACA,WAAA,KACA,iBAAA,gBAVF,aAaI,MAAA,KACA,gBAAA,KHwCA,yBGtDJ,WAkBI,UAAA,MCnBA,cAAA,KDwBJ,YACE,MAAA,KACA,YAAA,OAGF,kBACE,QAAA,MACA,MAAA,eE9BF,YACE,eAAA,EAAA,MAAA,EADF,mBC2KA,mBACA,mBDrKI,eAAA,KAPJ,2BCiLA,2BACA,2BDxKM,QAAA,MACA,OAAA,KACA,WAAA,MACA,QAAA,GAbN,kBAkBI,MAAA,KACA,UAAA,KACA,cAAA,KL+CA,4BKnEJ,kBAuBM,QAAA,MACA,WAAA,KAxBN,iCA2BQ,OAAA,GCiLR,8BADA,8BAGA,8BADA,8BAHA,8BD1MA,8BAsCU,QAAA,OACA,eAAA,IACA,OAAA,IAAA,MAAA,QC+KV,2CADA,2CAGA,2CADA,2CAHA,2CDrNA,2CA2CY,cAAA,EA3CZ,sCAmDM,YAAA,OAKN,kBACE,QAAA,MACA,eAAA,KAOF,eJkFQ,UAAA,KAsBA,0BIxGR,eJgHY,UAAA,uBIhHZ,eJkFQ,UAAA,QAsBA,0BIxGR,eJgHY,UAAA,qBIhHZ,eJkFQ,UAAA,OAsBA,0BIxGR,eJgHY,UAAA,uBIhHZ,iCAcI,WAAA,KAdJ,eAkBI,WAAA,OC0LJ,kBD5MA,kBAuBI,cAAA,OLlCA,yBM6NF,eACA,cDnNF,eA8BM,UAAA,KAKN,UACE,WAAA,KACA,cAAA,MACA,YAAA,IJ4CM,UAAA,KAsBA,0BIrER,UJ6EY,UAAA,wBItEZ,SJwCQ,UAAA,OItCN,YAAA,IJ4DM,0BI9DR,SJsEY,UAAA,uBD3HR,yBKqDJ,SAKI,UAAA,KAIJ,gBAAkB,MAAA,QAClB,uBAAyB,MAAA,QE3HzB,QACE,QAAA,MACA,QAAA,IACA,MAAA,KACA,WAAA,OACA,iBAAA,QACA,QAAA,ECMA,cDHE,MAAA,KAIJ,aACE,QAAA,KACA,QAAA,IAAA,OETF,QAOE,eAAA,EAAA,MAAA,EACA,YAAA,OACA,eAAA,ORgHI,UAAA,QQxHwB,2DAD9B,QAEI,SAAA,eAAA,SAAA,OACA,IAAA,KACA,OAAA,mBACA,WAAA,MAQJ,aACE,aAAA,EACA,YAAA,IAAA,MAAA,KAFF,gBAKI,aAAA,KAIJ,WACE,QAAA,MADF,aAII,QAAA,MACA,QAAA,QAAA,OACA,MAAA,QANJ,mBASM,MAAA,QACA,gBAAA,KASN,YACE,eAAA,EAAA,MAAA,EAEA,cAAA,IAAA,MAAA,eTUE,yBSbJ,YAYI,aAAA,IAAA,MAAA,eAN4B,2DANhC,YAOM,SAAA,eAAA,SAAA,OACA,IAAA,KACA,QAAA,KACA,OAAA,qBTGF,0BSbJ,YAgBI,SAAA,EAAA,EAAA,MAAA,KAAA,EAAA,EAAA,OAIJ,UACE,YAAA,KACA,eAAA,KACA,aAAA,MACA,YAAA,MTXE,yBSc4B,2DAPhC,UAQM,WAAA,mBACA,WAAA,OThBF,yBSOJ,UAeI,QAAA,iBAIJ,WACE,SAAA,SACA,QAAA,KAAA,KACA,aAAA,MACA,YAAA,MACA,cAAA,IAAA,MAAA,gBALF,+BAQI,aAAA,QACA,WAAA,EAAA,EAAA,EAAA,IAAA,qBAIJ,uBACE,YAAA,EACA,MAAA,QAGF,YACE,QAAA,KAGF,aACE,QAAA,MACA,QAAA,OAAA,OACA,YAAA,IACA,MAAA,gBAJF,mBAOI,MAAA,gBACA,gBAAA,KAIJ,oBAEI,cAAA,KAFJ,sCAKM,WAAA,KALN,iCASM,MAAA,gBATN,uCAYQ,iBAAA,YAZR,gCAiBM,QAAA,MAMN,sBACE,QAAA,MACA,QAAA,OAAA,ORzEE,UAAA,IQ2EF,MAAA,gBAGF,4BACE,MAAA,gBACA,gBAAA,KACA,iBAAA,YH8VF,iCG3VA,2BAEE,YAAA,IACA,MAAA,gBACA,iBAAA,YC5JF,WT2HM,UAAA,QSzHJ,WAAA,OACA,iBAAA,QAHF,aAMI,YAAA,IACA,MAAA,QAPJ,mBAAA,mBAWM,MAAA,QAXN,aAgBI,cAAA,EVwCA,yBUxDJ,WAoBI,WAAA,MAIJ,iBACE,aAAA,EACA,cAAA,KAFF,oBAKI,QAAA,aALJ,uBAQM,YAAA,KC9BN,0BL8hBA,mCK1hBM,YAAA,OACA,eAAA,OACA,iBAAA,oBACA,OAAA,IAAA,MAAA,mBAPN,0BAYI,WAAA,KL+hBJ,mCADA,mCK1iBA,gCAkBI,WAAA,KACA,iBAAA,iBAIJ,+BACE,WAAA,MACA,iBAAA,iBAGF,cACE,iBAAA,oBACA,OAAA,IAAA,MAAA,oBAIF,mBACE,MAAA,MCpCA,MAAA,KACA,cAAA,KACA,aAAA,KACA,aAAA,KACA,YAAA,KDoCF,aCtBE,QAAA,YAAA,QAAA,KACA,cAAA,KAAA,UAAA,KACA,aAAA,MACA,YAAA,MDuBF,sBCnBE,SAAA,SAIA,MAAA,KACA,cAAA,KACA,aAAA,KZwBE,yBWXJ,sBCTE,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,KZgBE,yBWXJ,sBCTE,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,YDiBF,2BC/BE,SAAA,SAIA,MAAA,KACA,cAAA,KACA,aAAA,KZwBE,yBWCJ,2BCrBE,SAAA,EAAA,EAAA,IAAA,KAAA,EAAA,EAAA,IAIA,UAAA,KZgBE,yBWCJ,2BCrBE,SAAA,EAAA,EAAA,WAAA,KAAA,EAAA,EAAA,WAIA,UAAA,YDkCF,sBACE,UAAA,MACA,UAAA,MACA,aAAA,KACA,YAAA,KAGF,6BACE,OAAA,KACA,cAAA,MACA,iBAAA,KPnFE,cAAA,OOuFJ,8BACE,MAAA,MACA,MAAA,KACA,OAAA,KACA,iBAAA,QP3FE,cAAA,OO+FJ,2BACE,OAAA,KACA,aAAA,OACA,iBAAA,QPlGE,cAAA,OOsGJ,4BACE,UAAA,KAQF,YACE,SAAA,SACA,QAAA,KACA,OAAA,KAAA,MAAA,EACA,OAAA,MAAA,QACA,aAAA,MAAA,EAAA,EExHA,mBACE,QAAA,MACA,MAAA,KACA,QAAA,GbwDA,yBWwDJ,YASI,QAAA,OACA,aAAA,EACA,YAAA,EACA,aAAA,OLyjBJ,kCKrkBA,uBAiBI,WAAA,EAjBJ,cAqBI,WAAA,KArBJ,qBAyBI,SAAA,SACA,OAAA,MXlFA,yBWwDJ,qBA6BM,OAAA,SA7BN,kEAkCI,QAAA,SAlCJ,wCAuCM,WAAA,ML0jBN,0BKjmBA,sBLkmBA,4BAEA,2BADA,gCKnjBI,WAAA,KAhDJ,uCAoDI,SAAA,OACA,QAAA,MArDJ,mCAyDI,cAAA,EAzDJ,mBA6DI,MAAA,KAKJ,2BAGM,QAAA,KAAA,EACA,aAAA,KAJN,0CAOM,WAAA,EAPN,oBL6jBA,oBACA,oBACA,oBACA,oBACA,oBKhjBI,WAAA,EACA,cAAA,EAKJ,yBACE,QAAA,KLmjBF,oBK/iBA,oBAGI,YAAA,MAKJ,iBL4iBA,uBKziBI,WAAA,OACA,cAAA,OAJJ,sCAOI,WAAA,ML+iBJ,6DK1iBA,kCAEE,WAAA,MAEF,8BACE,cAAA,MAEF,kCACE,OAAA,SAIF,wBACE,UAAA,MAEF,2CACE,UAAA,KAIF,uBL2iBA,wBKxiBI,SAAA,OACA,OAAA,MAAA,MAAA,KAJJ,0BAOI,SAAA,OACA,OAAA,KAAA,MAAA,MXtMA,yBW8LJ,uBLujBE,wBKziBI,OAAA,QAAA,QAAA,KAdN,0BAiBM,OAAA,KAAA,QAAA,SAMN,wBACE,WAAA,MACA,cAAA,MAIF,OACE,QAAA,KL2iBF,gBK5iBA,gBAKI,QAAA,KAIJ,gBACE,QAAA,KAGF,kBACE,iBAAA,QADF,yBAII,SAAA,SACA,IAAA,KACA,MAAA,KACA,OAAA,KACA,KAAA,KACA,QAAA,EACA,QAAA,MAVJ,gCAcI,KAAA,KACA,aAAA,KACA,YAAA,KAKJ,2BACE,cAAA,KAIF,2BACE,eAAA,OACA,iBAAA,QAFF,oCAKI,SAAA,SACA,QAAA,MACA,MAAA,KACA,MAAA,MACA,OAAA,QAKJ,gBACE,YAAA,OAGF,oCACE,SAAA,SACA,QAAA,aACA,OAAA,KAAA,KACA,QAAA,EAIF,mBACE,SAAA,SACA,OAAA,MACA,WAAA,MACA,SAAA,KAGF,qBACE,SAAA,SACA,OAAA,MACA,SAAA,KAGF,yCAEI,QAAA,aACA,MAAA,KACA,OAAA,KACA,OAAA,OACA,iBAAA,QAIJ,2CAEI,OAAA,IAAA,MAAA,QAQJ,WACE,QAAA,KACA,WAAA,KACA,cAAA,KACA,iBAAA,QACA,mBAAA,yBXlUE,yBW6TJ,WAQI,QAAA,QAIJ,uBACE,aAAA,MACA,YAAA,MX3UE,yBWyUJ,uBAKI,aAAA,EACA,YAAA,GAIJ,eAEI,QAAA,EACA,WAAA,EACA,cAAA,EACA,iBAAA,YACA,OAAA,EANJ,oBVvUI,UAAA,QUiVA,MAAA,QGrZJ,gBACE,YAAA,IACA,MAAA,QACA,aAAA,QAHF,uBAAA,sBAOI,MAAA,KACA,iBAAA,QACA,aAAA,QATJ,sBAaI,WAAA,EAAA,EAAA,EAAA,IAAA,qBAIJ,iBACE,YAAA,IACA,MAAA,QACA,aAAA,QAHF,wBAAA,uBAOI,MAAA,QACA,iBAAA,QACA,aAAA,QATJ,uBAaI,WAAA,EAAA,EAAA,EAAA,IAAA,sBC9BJ,YACE,QAAA,QACA,WAAA,QACA,cAAA,QACA,OAAA,IAAA,MAAA,KACA,kBAAA,OXJE,cAAA,OWDJ,eASI,WAAA,EACA,cAAA,OAVJ,yBAcI,cAAA,EAdJ,iBXCI,cAAA,OWDJ,wBAsBI,WAAA,QAWJ,iBALE,kBAAA,QAEA,oBAAK,MAAA,QAIP,oBANE,kBAAA,QAEA,uBAAK,MAAA,QAKP,mBAPE,kBAAA,QAEA,sBAAK,MAAA,QC9BP,sBAEI,cAAA,EAFJ,gCAKI,MAAA,ICJJ,gBACE,QAAA,MACA,MAAA,KACA,cAAA,KACA,SAAA,OACA,MAAA,QACA,iBAAA,QbNE,cAAA,OaAJ,yBAUI,MAAA,KACA,iBAAA,QAKJ,eACE,QAAA,KAAA,EACA,WAAA,OAFF,8BAKI,WAAA,IAAA,MAAA,KALJ,kBXyhCA,kBW9gCI,WAAA,EACA,cAAA,EjB2BA,yBiBvCJ,eAgBI,QAAA,WACA,MAAA,GAjBJ,8BAoBM,WAAA,EACA,YAAA,IAAA,MAAA,KArBN,kBhBoIQ,UAAA,MAsBA,gDgB1JR,kBhBkKY,UAAA,wBgB/HZ,gBACE,OAAA,EAAA,KACA,SAAA,OAFF,2BAMI,iBAAA,QANJ,iCASI,iBAAA,QATJ,mCAYI,iBAAA,QAZJ,yBAeI,iBAAA,QAIJ,cACE,MAAA,KACA,MAAA,KACA,OAAA,KACA,aAAA,OACA,YAAA,Ob3EE,cAAA,OJuDA,yBiBeJ,cASI,MAAA,KACA,OAAA,MChFF,aACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,eACE,MAAA,QACA,iBAAA,QAFF,eACE,MAAA,QACA,iBAAA,QAFF,cACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,cACE,MAAA,QACA,iBAAA,KAFF,aACE,MAAA,KACA,iBAAA,QAFF,kBACE,MAAA,KACA,iBAAA,QAKF,gBACE,MAAA,KACA,iBAAA,QAFF,kBACE,MAAA,KACA,iBAAA,QAFF,gBACE,MAAA,KACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAFF,gBACE,MAAA,QACA,iBAAA,QAFF,eACE,MAAA,KACA,iBAAA,QAFF,cACE,MAAA,QACA,iBAAA,QAFF,aACE,MAAA,KACA,iBAAA,QAKF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,QACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QAFF,YACE,MAAA,KACA,iBAAA,QCjBJ,cACE,SAAA,SACA,QAAA,KACA,MAAA,MAHF,yBAMI,WAAA,EnBkDA,yBmBxDJ,cAUI,QAAA,OAIJ,eACE,SAAA,SACA,IAAA,MACA,MAAA,MACA,QAAA,GACA,QAAA,MACA,QAAA,OAAA,MlBgDE,UAAA,IkB9CF,MAAA,QACA,iBAAA,YACA,OAAA,EfvBE,cAAA,OeaJ,qBAcI,MAAA,KACA,iBAAA,QC3BJ,oBnByHM,UAAA,SmBvHJ,YAAA,OACA,oBAAA,KAAA,iBAAA,KAAA,gBAAA,KAAA,YAAA,KAGF,uBnB6IQ,UAAA,OAsBA,0BmBnKR,uBnB2KY,UAAA,wBoBrLZ,KAAO,iBAAA,KACP,GAAK,MAAA,KACL,GAAK,MAAA,KACL,GAAK,MAAA,KACL,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,iBAAA,KAAwB,OAAA,IAAA,MAAA,KAC9B,IAAM,WAAA,OACN,IAAM,MAAA,IACN,IAAM,MAAA,KACN,IAAM,iBAAA,KAAwB,OAAA,IAAA,MAAA,KAC9B,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,GAAK,MAAA,KACL,GAAK,MAAA,QACL,IAAM,MAAA,QACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,QACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,GAAK,MAAA,KACL,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,WAAA,OAAoB,MAAA,KAC1B,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,KACN,IAAM,MAAA,Kf6+CN,ae3+CA,Qf0+CA,Yex+CiB,MAAA,KAEjB,uBf4+CA,qBe1+CE,MAAA,KACA,QAAA,KACA,oBAAA,KAAA,iBAAA,KAAA,gBAAA,KAAA,YAAA,KAGF,6BACE,MAAA,KACA,QAAA,OACA,oBAAA,KAAA,iBAAA,KAAA,gBAAA,KAAA,YAAA,KC5EF,eACE,YAAA,IACA,MAAA,mBCII,WAAA,MAAA,KAAA,WAAA,CAAA,QAAA,KAAA,YAKF,uCDXJ,eCYM,WAAA,MDZN,qBAMI,MAAA,QACA,gBAAA,KEFJ,sBACE,QAAA,gBACA,SAAA,EAAA,KAAA,EAFF,wCAMI,MAAA,KACA,UAAA,YACA,UAAA,eACA,QAAA,OAAA,YACA,iBAAA,KACA,gBAAA,YACA,OAAA,IAAA,MAAA,eACA,WAAA,EAAA,MAAA,KAAA,iBxB0CA,yBwBvDJ,wCAgBM,MAAA,MAhBN,gDAqBM,QAAA,eArBN,6DAyBM,QAAA,YACA,SAAA,kBACA,iBAAA,sBACA,OAAA,YA5BN,wDAgCM,WAAA,YAhCN,oDAqCI,QAAA,YACA,SAAA,kBAtCJ,qEA0CI,QAAA,QAAA,eACA,WAAA,YvB+EE,UAAA,kBuB7EF,YAAA,cACA,MAAA,kBACA,cAAA,YA/CJ,6DAmDI,MAAA,eACA,YAAA,YApDJ,wEAyDI,MAAA,eACA,MAAA,eACA,QAAA,YACA,WAAA,eA5DJ,wEAgEI,QAAA,gBvB0DE,UAAA,QuBxDF,MAAA,QAlEJ,+EAqEM,QAAA,EAAA,OACA,QAAA,IAtEN,6DA2EI,QAAA,YAAA,QAAA,KACA,cAAA,KAAA,UAAA,KACA,MAAA,eACA,MAAA,eACA,QAAA,OAAA,eA/EJ,qEAmFM,QAAA,eAnFN,sGA0FQ,YAAA,iBACA,WAAA,iBACA,WAAA,IAAA,MAAA,eA5FR,uFAiGM,QAAA,eAjGN,2DAsGI,QAAA,MACA,cAAA,YvBmBE,UAAA,kBuBjBF,YAAA,cAzGJ,0DA6GI,SAAA,EAAA,EAAA,KAAA,KAAA,EAAA,EAAA,KACA,UAAA,KACA,QAAA,MAAA,EvBWE,UAAA,mBuBTF,YAAA,IACA,YAAA,eACA,MAAA,QAnHJ,gDAuHI,MAAA,eACA,MAAA,eACA,OAAA,eACA,QAAA,OAAA,KAAA,EvBAE,UAAA,iBuBEF,YAAA,YACA,MAAA,kBACA,WAAA,IAAA,MAAA,eA9HJ,sDAkII,QAAA,iBACA,SAAA,kBACA,MAAA,kBACA,YAAA,YACA,WAAA,cAtIJ,+DA0II,MAAA,QACA,iBAAA,sBA3IJ,mGA+II,WAAA,MAAA,EAAA,KAAA,EAAA,EAAA,6BA/IJ,sFAmJI,iBAAA","sourcesContent":["/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License.\n * For details, see https://creativecommons.org/licenses/by/3.0/.\n */\n\n// Dev notes\n//\n// Background information on nomenclature and architecture decisions here.\n//\n// - Bootstrap functions, variables, and mixins are included for easy reuse.\n// Doing so gives us access to the same core utilities provided by Bootstrap.\n// For example, consistent media queries through those mixins.\n//\n// - Bootstrap's **docs variables** are prefixed with `$bd-`.\n// These custom colors avoid collision with the components Bootstrap provides.\n//\n// - Classes are prefixed with `.bd-`.\n// These classes indicate custom-built or modified components for the design\n// and layout of the Bootstrap docs. They are not included in our builds.\n//\n// Happy Bootstrapping!\n\n// Load Bootstrap variables and mixins\n@import \"../../../../../scss/functions\";\n@import \"../../../../../scss/variables\";\n@import \"../../../../../scss/mixins\";\n\n// Load docs components\n@import \"variables\";\n@import \"nav\";\n@import \"masthead\";\n@import \"ads\";\n@import \"content\";\n@import \"skippy\";\n@import \"sidebar\";\n@import \"footer\";\n@import \"component-examples\";\n@import \"buttons\";\n@import \"callouts\";\n@import \"browser-bugs\";\n@import \"brand\";\n@import \"colors\";\n@import \"clipboard-js\";\n@import \"placeholder-img\";\n\n// Load docs dependencies\n@import \"syntax\";\n@import \"anchor\";\n@import \"algolia\";\n","//\n// Main navbar\n//\n\n.bd-navbar {\n min-height: 4rem;\n background-color: $bd-purple;\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .1);\n\n @include media-breakpoint-down(md) {\n padding-right: .5rem;\n padding-left: .5rem;\n\n .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n\n .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n }\n }\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 0;\n z-index: 1071; // over everything in bootstrap\n }\n }\n\n .navbar-nav {\n .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: $bd-purple-light;\n\n &.active,\n &:hover {\n color: $white;\n background-color: transparent;\n }\n\n &.active {\n font-weight: 600;\n }\n }\n }\n\n .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n }\n\n .dropdown-menu {\n @include font-size(.875rem);\n }\n\n .dropdown-item.active {\n font-weight: 600;\n color: $gray-900;\n background-color: transparent;\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: .4rem .6rem;\n background-size: .75rem .75rem;\n }\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width. Null for the largest (last) breakpoint.\n// The maximum value is calculated as the minimum of the next one less 0.02px\n// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $next: breakpoint-next($name, $breakpoints);\n @return if($next, breakpoint-min($next, $breakpoints) - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $max: breakpoint-max($name, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($name, $breakpoints) {\n @content;\n }\n }\n}\n","// stylelint-disable property-blacklist, scss/dollar-variable-default\n\n// SCSS RFS mixin\n//\n// Automated font-resizing\n//\n// See https://github.com/twbs/rfs\n\n// Configuration\n\n// Base font size\n$rfs-base-font-size: 1.25rem !default;\n$rfs-font-size-unit: rem !default;\n\n// Breakpoint at where font-size starts decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n// Resize font-size based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != \"number\" or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-responsive-font-sizes to false\n$enable-responsive-font-sizes: true !default;\n\n// Cache $rfs-base-font-size unit\n$rfs-base-font-size-unit: unit($rfs-base-font-size);\n\n// Remove px-unit from $rfs-base-font-size for calculations\n@if $rfs-base-font-size-unit == \"px\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1);\n}\n@else if $rfs-base-font-size-unit == \"rem\" {\n $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value);\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == \"px\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == \"rem\" or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);\n}\n\n// Responsive font-size mixin\n@mixin rfs($fs, $important: false) {\n // Cache $fs unit\n $fs-unit: if(type-of($fs) == \"number\", unit($fs), false);\n\n // Add !important suffix if needed\n $rfs-suffix: if($important, \" !important\", \"\");\n\n // If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $fs-unit or $fs-unit != \"\" and $fs-unit != \"px\" and $fs-unit != \"rem\" or $fs == 0 {\n font-size: #{$fs}#{$rfs-suffix};\n }\n @else {\n // Variables for storing static and fluid rescaling\n $rfs-static: null;\n $rfs-fluid: null;\n\n // Remove px-unit from $fs for calculations\n @if $fs-unit == \"px\" {\n $fs: $fs / ($fs * 0 + 1);\n }\n @else if $fs-unit == \"rem\" {\n $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);\n }\n\n // Set default font-size\n @if $rfs-font-size-unit == rem {\n $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix};\n }\n @else if $rfs-font-size-unit == px {\n $rfs-static: #{$fs}px#{$rfs-suffix};\n }\n @else {\n @error \"`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`.\";\n }\n\n // Only add media query if font-size is bigger as the minimum font-size\n // If $rfs-factor == 1, no rescaling will take place\n @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes {\n $min-width: null;\n $variable-unit: null;\n\n // Calculate minimum font-size for given font-size\n $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;\n\n // Calculate difference between given font-size and minimum font-size for given font-size\n $fs-diff: $fs - $fs-min;\n\n // Base font-size formatting\n // No need to check if the unit is valid, because we did that before\n $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);\n\n // If two-dimensional, use smallest of screen width and height\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};\n\n // Set the calculated font-size.\n $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};\n }\n\n // Rendering\n @if $rfs-fluid == null {\n // Only render static font-size if no fluid font-size is available\n font-size: $rfs-static;\n }\n @else {\n $mq-value: null;\n\n // RFS breakpoint formatting\n @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem {\n $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit};\n }\n @else if $rfs-breakpoint-unit == px {\n $mq-value: #{$rfs-breakpoint}px;\n }\n @else {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n }\n\n @if $rfs-class == \"disable\" {\n // Adding an extra class increases specificity,\n // which prevents the media query to override the font size\n &,\n .disable-responsive-font-size &,\n &.disable-responsive-font-size {\n font-size: $rfs-static;\n }\n }\n @else {\n font-size: $rfs-static;\n }\n\n @if $rfs-two-dimensional {\n @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n @else {\n @media (max-width: #{$mq-value}) {\n @if $rfs-class == \"enable\" {\n .enable-responsive-font-size &,\n &.enable-responsive-font-size {\n font-size: $rfs-fluid;\n }\n }\n @else {\n font-size: $rfs-fluid;\n }\n\n @if $rfs-safari-iframe-resize-bug-fix {\n // stylelint-disable-next-line length-zero-no-unit\n min-width: 0vw;\n }\n }\n }\n }\n }\n}\n\n// The font-size & responsive-font-size mixin uses RFS to rescale font sizes\n@mixin font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n\n@mixin responsive-font-size($fs, $important: false) {\n @include rfs($fs, $important);\n}\n","// stylelint-disable declaration-no-important\n\n.bd-masthead {\n position: relative;\n padding: 3rem ($grid-gutter-width / 2);\n // background-image: linear-gradient(45deg, #fafafa, #f5f5f5);\n\n h1 {\n @include font-size(4rem);\n line-height: 1;\n }\n\n .btn {\n padding: .8rem 2rem;\n font-weight: 600;\n @include font-size(1.25rem);\n }\n\n .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n }\n\n @include media-breakpoint-up(sm) {\n padding-top: 5rem;\n padding-bottom: 5rem;\n\n .carbonad {\n margin-bottom: 0 !important;\n }\n }\n\n @include media-breakpoint-up(md) {\n .carbonad {\n margin-top: 3rem !important;\n }\n }\n}\n\n.half-rule {\n width: 6rem;\n margin: 2.5rem 0;\n}\n\n.masthead-followup {\n .bd-clipboard { display: none; }\n\n .highlight {\n padding: .5rem 0;\n background-color: transparent;\n }\n}\n","// stylelint-disable declaration-no-important, selector-max-id\n\n//\n// Carbon ads\n//\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n @include font-size(.8125rem);\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, .05);\n\n a {\n color: #333;\n text-decoration: none;\n }\n\n @include media-breakpoint-up(sm) {\n max-width: 330px;\n @include border-radius(4px);\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n color: #777 !important;\n}\n","// stylelint-disable property-blacklist\n// Single side border-radius\n\n@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {\n @if $enable-rounded {\n border-radius: $radius;\n }\n @else if $fallback-border-radius != false {\n border-radius: $fallback-border-radius;\n }\n}\n\n@mixin border-top-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n border-bottom-left-radius: $radius;\n }\n}\n\n@mixin border-top-left-radius($radius) {\n @if $enable-rounded {\n border-top-left-radius: $radius;\n }\n}\n\n@mixin border-top-right-radius($radius) {\n @if $enable-rounded {\n border-top-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-right-radius($radius) {\n @if $enable-rounded {\n border-bottom-right-radius: $radius;\n }\n}\n\n@mixin border-bottom-left-radius($radius) {\n @if $enable-rounded {\n border-bottom-left-radius: $radius;\n }\n}\n","// stylelint-disable no-duplicate-selectors, selector-max-combinators, selector-max-compound-selectors, selector-max-type, selector-no-qualifying-type\n\n//\n// Automatically style Markdown-based tables like a Bootstrap `.table`.\n//\n\n.bd-content {\n order: 1;\n\n // Hack the sticky header\n > h2[id],\n > h3[id],\n > h4[id] {\n pointer-events: none;\n\n &::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n content: \"\";\n }\n }\n\n > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n\n @include media-breakpoint-down(md) {\n display: block;\n overflow-x: auto;\n\n &.table-bordered {\n border: 0;\n }\n }\n\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: $table-cell-padding;\n vertical-align: top;\n border: 1px solid $table-border-color;\n\n > p:last-child {\n margin-bottom: 0;\n }\n }\n }\n }\n\n // Prevent breaking of code (e.g., Grunt tasks list)\n td:first-child > code {\n white-space: nowrap;\n }\n }\n}\n\n.bd-content-title {\n display: block;\n pointer-events: auto;\n}\n\n//\n// Docs sections\n//\n\n.bd-content {\n > h2 {\n @include font-size($h2-font-size);\n }\n\n > h3 {\n @include font-size($h3-font-size);\n }\n\n > h4 {\n @include font-size($h4-font-size);\n }\n\n > h2:not(:first-child) {\n margin-top: 3rem;\n }\n\n > h3 {\n margin-top: 1.5rem;\n }\n\n > ul li,\n > ol li {\n margin-bottom: .25rem;\n }\n\n @include media-breakpoint-up(lg) {\n > ul,\n > ol,\n > p {\n max-width: 80%;\n }\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n font-weight: 300;\n @include font-size(3rem);\n}\n\n.bd-lead {\n @include font-size(1.5rem);\n font-weight: 300;\n\n @include media-breakpoint-up(lg) {\n max-width: 80%;\n }\n}\n\n.bd-text-purple { color: $bd-purple; }\n.bd-text-purple-bright { color: $bd-purple-bright; }\n","/*!\n * Bootstrap Docs (https://getbootstrap.com/)\n * Copyright 2011-2019 The Bootstrap Authors\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under the Creative Commons Attribution 3.0 Unported License.\n * For details, see https://creativecommons.org/licenses/by/3.0/.\n */\n.bd-navbar {\n min-height: 4rem;\n background-color: #563d7c;\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.05), inset 0 -1px 0 rgba(0, 0, 0, 0.1);\n}\n\n@media (max-width: 991.98px) {\n .bd-navbar {\n padding-right: .5rem;\n padding-left: .5rem;\n }\n .bd-navbar .navbar-nav-scroll {\n max-width: 100%;\n height: 2.5rem;\n margin-top: .25rem;\n overflow: hidden;\n }\n .bd-navbar .navbar-nav-scroll .navbar-nav {\n padding-bottom: 2rem;\n overflow-x: auto;\n white-space: nowrap;\n -webkit-overflow-scrolling: touch;\n }\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-navbar {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1071;\n }\n }\n}\n\n.bd-navbar .navbar-nav .nav-link {\n padding-right: .5rem;\n padding-left: .5rem;\n color: #cbbde2;\n}\n\n.bd-navbar .navbar-nav .nav-link.active, .bd-navbar .navbar-nav .nav-link:hover {\n color: #fff;\n background-color: transparent;\n}\n\n.bd-navbar .navbar-nav .nav-link.active {\n font-weight: 600;\n}\n\n.bd-navbar .navbar-nav-svg {\n display: inline-block;\n width: 1rem;\n height: 1rem;\n vertical-align: text-top;\n}\n\n.bd-navbar .dropdown-menu {\n font-size: 0.875rem;\n}\n\n.bd-navbar .dropdown-item.active {\n font-weight: 600;\n color: #212529;\n background-color: transparent;\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: .4rem .6rem;\n background-size: .75rem .75rem;\n}\n\n.bd-masthead {\n position: relative;\n padding: 3rem 15px;\n}\n\n.bd-masthead h1 {\n font-size: 4rem;\n line-height: 1;\n}\n\n@media (max-width: 1200px) {\n .bd-masthead h1 {\n font-size: calc(1.525rem + 3.3vw) ;\n }\n}\n\n.bd-masthead .btn {\n padding: .8rem 2rem;\n font-weight: 600;\n font-size: 1.25rem;\n}\n\n.bd-masthead .carbonad {\n margin-top: 0 !important;\n margin-bottom: -3rem !important;\n}\n\n@media (min-width: 576px) {\n .bd-masthead {\n padding-top: 5rem;\n padding-bottom: 5rem;\n }\n .bd-masthead .carbonad {\n margin-bottom: 0 !important;\n }\n}\n\n@media (min-width: 768px) {\n .bd-masthead .carbonad {\n margin-top: 3rem !important;\n }\n}\n\n.half-rule {\n width: 6rem;\n margin: 2.5rem 0;\n}\n\n.masthead-followup .bd-clipboard {\n display: none;\n}\n\n.masthead-followup .highlight {\n padding: .5rem 0;\n background-color: transparent;\n}\n\n#carbonads {\n position: static;\n display: block;\n max-width: 400px;\n padding: 15px 15px 15px 160px;\n margin: 2rem 0;\n overflow: hidden;\n font-size: 0.8125rem;\n line-height: 1.4;\n text-align: left;\n background-color: rgba(0, 0, 0, 0.05);\n}\n\n#carbonads a {\n color: #333;\n text-decoration: none;\n}\n\n@media (min-width: 576px) {\n #carbonads {\n max-width: 330px;\n border-radius: 4px;\n }\n}\n\n.carbon-img {\n float: left;\n margin-left: -145px;\n}\n\n.carbon-poweredby {\n display: block;\n color: #777 !important;\n}\n\n.bd-content {\n -ms-flex-order: 1;\n order: 1;\n}\n\n.bd-content > h2[id],\n.bd-content > h3[id],\n.bd-content > h4[id] {\n pointer-events: none;\n}\n\n.bd-content > h2[id]::before,\n.bd-content > h3[id]::before,\n.bd-content > h4[id]::before {\n display: block;\n height: 6rem;\n margin-top: -6rem;\n content: \"\";\n}\n\n.bd-content > table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 1rem;\n}\n\n@media (max-width: 991.98px) {\n .bd-content > table {\n display: block;\n overflow-x: auto;\n }\n .bd-content > table.table-bordered {\n border: 0;\n }\n}\n\n.bd-content > table > thead > tr > th,\n.bd-content > table > thead > tr > td,\n.bd-content > table > tbody > tr > th,\n.bd-content > table > tbody > tr > td,\n.bd-content > table > tfoot > tr > th,\n.bd-content > table > tfoot > tr > td {\n padding: 0.75rem;\n vertical-align: top;\n border: 1px solid #dee2e6;\n}\n\n.bd-content > table > thead > tr > th > p:last-child,\n.bd-content > table > thead > tr > td > p:last-child,\n.bd-content > table > tbody > tr > th > p:last-child,\n.bd-content > table > tbody > tr > td > p:last-child,\n.bd-content > table > tfoot > tr > th > p:last-child,\n.bd-content > table > tfoot > tr > td > p:last-child {\n margin-bottom: 0;\n}\n\n.bd-content > table td:first-child > code {\n white-space: nowrap;\n}\n\n.bd-content-title {\n display: block;\n pointer-events: auto;\n}\n\n.bd-content > h2 {\n font-size: 2rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h2 {\n font-size: calc(1.325rem + 0.9vw) ;\n }\n}\n\n.bd-content > h3 {\n font-size: 1.75rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h3 {\n font-size: calc(1.3rem + 0.6vw) ;\n }\n}\n\n.bd-content > h4 {\n font-size: 1.5rem;\n}\n\n@media (max-width: 1200px) {\n .bd-content > h4 {\n font-size: calc(1.275rem + 0.3vw) ;\n }\n}\n\n.bd-content > h2:not(:first-child) {\n margin-top: 3rem;\n}\n\n.bd-content > h3 {\n margin-top: 1.5rem;\n}\n\n.bd-content > ul li,\n.bd-content > ol li {\n margin-bottom: .25rem;\n}\n\n@media (min-width: 992px) {\n .bd-content > ul,\n .bd-content > ol,\n .bd-content > p {\n max-width: 80%;\n }\n}\n\n.bd-title {\n margin-top: 1rem;\n margin-bottom: .5rem;\n font-weight: 300;\n font-size: 3rem;\n}\n\n@media (max-width: 1200px) {\n .bd-title {\n font-size: calc(1.425rem + 2.1vw) ;\n }\n}\n\n.bd-lead {\n font-size: 1.5rem;\n font-weight: 300;\n}\n\n@media (max-width: 1200px) {\n .bd-lead {\n font-size: calc(1.275rem + 0.3vw) ;\n }\n}\n\n@media (min-width: 992px) {\n .bd-lead {\n max-width: 80%;\n }\n}\n\n.bd-text-purple {\n color: #563d7c;\n}\n\n.bd-text-purple-bright {\n color: #7952b3;\n}\n\n.skippy {\n display: block;\n padding: 1em;\n color: #fff;\n text-align: center;\n background-color: #563d7c;\n outline: 0;\n}\n\n.skippy:hover {\n color: #fff;\n}\n\n.skippy-text {\n padding: .5em;\n outline: 1px dotted;\n}\n\n.bd-toc {\n -ms-flex-order: 2;\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n font-size: 0.875rem;\n}\n\n@supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-toc {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n height: calc(100vh - 4rem);\n overflow-y: auto;\n }\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n}\n\n.section-nav ul {\n padding-left: 1rem;\n}\n\n.toc-entry {\n display: block;\n}\n\n.toc-entry a {\n display: block;\n padding: .125rem 1.5rem;\n color: #77757a;\n}\n\n.toc-entry a:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.bd-sidebar {\n -ms-flex-order: 0;\n order: 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n@media (min-width: 768px) {\n .bd-sidebar {\n border-right: 1px solid rgba(0, 0, 0, 0.1);\n }\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-sidebar {\n position: -webkit-sticky;\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: calc(100vh - 4rem);\n }\n }\n}\n\n@media (min-width: 1200px) {\n .bd-sidebar {\n -ms-flex: 0 1 320px;\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 768px) {\n @supports ((position: -webkit-sticky) or (position: sticky)) {\n .bd-links {\n max-height: calc(100vh - 9rem);\n overflow-y: auto;\n }\n }\n}\n\n@media (min-width: 768px) {\n .bd-links {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative;\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n}\n\n.bd-search .form-control:focus {\n border-color: #7952b3;\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.bd-search-docs-toggle {\n line-height: 1;\n color: #212529;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 600;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-toc-link:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n}\n\n.bd-toc-item.active {\n margin-bottom: 1rem;\n}\n\n.bd-toc-item.active:not(:first-child) {\n margin-top: 1rem;\n}\n\n.bd-toc-item.active > .bd-toc-link {\n color: rgba(0, 0, 0, 0.85);\n}\n\n.bd-toc-item.active > .bd-toc-link:hover {\n background-color: transparent;\n}\n\n.bd-toc-item.active > .bd-sidenav {\n display: block;\n}\n\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n font-size: 90%;\n color: rgba(0, 0, 0, 0.65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 600;\n color: rgba(0, 0, 0, 0.85);\n background-color: transparent;\n}\n\n.bd-footer {\n font-size: 0.875rem;\n text-align: center;\n background-color: #f7f7f7;\n}\n\n.bd-footer a {\n font-weight: 600;\n color: #495057;\n}\n\n.bd-footer a:hover, .bd-footer a:focus {\n color: #007bff;\n}\n\n.bd-footer p {\n margin-bottom: 0;\n}\n\n@media (min-width: 576px) {\n .bd-footer {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n}\n\n.bd-footer-links li {\n display: inline-block;\n}\n\n.bd-footer-links li + li {\n margin-left: 1rem;\n}\n\n.bd-example-row .row > .col,\n.bd-example-row .row > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.2);\n}\n\n.bd-example-row .row + .row {\n margin-top: 1rem;\n}\n\n.bd-example-row .flex-items-top,\n.bd-example-row .flex-items-middle,\n.bd-example-row .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, 0.1);\n}\n\n.bd-highlight {\n background-color: rgba(86, 61, 124, 0.15);\n border: 1px solid rgba(86, 61, 124, 0.15);\n}\n\n.example-container {\n width: 800px;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n\n.example-row {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n margin-right: -15px;\n margin-left: -15px;\n}\n\n.example-content-main {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-main {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-main {\n -ms-flex: 0 0 66.666667%;\n flex: 0 0 66.666667%;\n max-width: 66.666667%;\n }\n}\n\n.example-content-secondary {\n position: relative;\n width: 100%;\n padding-right: 15px;\n padding-left: 15px;\n}\n\n@media (min-width: 576px) {\n .example-content-secondary {\n -ms-flex: 0 0 50%;\n flex: 0 0 50%;\n max-width: 50%;\n }\n}\n\n@media (min-width: 992px) {\n .example-content-secondary {\n -ms-flex: 0 0 33.333333%;\n flex: 0 0 33.333333%;\n max-width: 33.333333%;\n }\n}\n\n.bd-example-container {\n min-width: 16rem;\n max-width: 25rem;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-container-header {\n height: 3rem;\n margin-bottom: .5rem;\n background-color: white;\n border-radius: 0.25rem;\n}\n\n.bd-example-container-sidebar {\n float: right;\n width: 4rem;\n height: 8rem;\n background-color: #80bdff;\n border-radius: 0.25rem;\n}\n\n.bd-example-container-body {\n height: 8rem;\n margin-right: 4.5rem;\n background-color: #957bbe;\n border-radius: 0.25rem;\n}\n\n.bd-example-container-fluid {\n max-width: none;\n}\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem -15px 0;\n border: solid #f8f9fa;\n border-width: .2rem 0 0;\n}\n\n.bd-example::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n@media (min-width: 576px) {\n .bd-example {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n}\n\n.bd-example + .highlight,\n.bd-example + .clipboard + .highlight {\n margin-top: 0;\n}\n\n.bd-example + p {\n margin-top: 2rem;\n}\n\n.bd-example .pos-f-t {\n position: relative;\n margin: -1rem;\n}\n\n@media (min-width: 576px) {\n .bd-example .pos-f-t {\n margin: -1.5rem;\n }\n}\n\n.bd-example .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n}\n\n.bd-example > .form-control + .form-control {\n margin-top: .5rem;\n}\n\n.bd-example > .nav + .nav,\n.bd-example > .alert + .alert,\n.bd-example > .navbar + .navbar,\n.bd-example > .progress + .progress,\n.bd-example > .progress + .btn {\n margin-top: 1rem;\n}\n\n.bd-example > .dropdown-menu:first-child {\n position: static;\n display: block;\n}\n\n.bd-example > .form-group:last-child {\n margin-bottom: 0;\n}\n\n.bd-example > .close {\n float: none;\n}\n\n.bd-example-type .table td {\n padding: 1rem 0;\n border-color: #eee;\n}\n\n.bd-example-type .table tr:first-child td {\n border-top: 0;\n}\n\n.bd-example-type h1,\n.bd-example-type h2,\n.bd-example-type h3,\n.bd-example-type h4,\n.bd-example-type h5,\n.bd-example-type h6 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n.bd-example > svg + svg,\n.bd-example > img + img {\n margin-left: .5rem;\n}\n\n.bd-example > .btn,\n.bd-example > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n}\n\n.bd-example > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n}\n\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n.bd-example > .list-group {\n max-width: 400px;\n}\n\n.bd-example > [class*=\"list-group-horizontal\"] {\n max-width: 100%;\n}\n\n.bd-example .fixed-top,\n.bd-example .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n}\n\n.bd-example .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n}\n\n@media (min-width: 576px) {\n .bd-example .fixed-top,\n .bd-example .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .bd-example .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n}\n\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n.modal {\n z-index: 1072;\n}\n\n.modal .tooltip,\n.modal .popover {\n z-index: 1073;\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n}\n\n.bd-example-modal .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n}\n\n.bd-example-modal .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n}\n\n.bd-example-popover-static .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n}\n\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n}\n\n.bd-example-border-utils-0 [class^=\"border\"] {\n border: 1px solid #dee2e6;\n}\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: #f8f9fa;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n}\n\n@media (min-width: 576px) {\n .highlight {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: -15px;\n margin-left: -15px;\n}\n\n@media (min-width: 576px) {\n .bd-content .highlight {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight pre {\n padding: 0;\n margin-top: 0;\n margin-bottom: 0;\n background-color: transparent;\n border: 0;\n}\n\n.highlight pre code {\n font-size: inherit;\n color: #212529;\n}\n\n.btn-bd-primary {\n font-weight: 600;\n color: #7952b3;\n border-color: #7952b3;\n}\n\n.btn-bd-primary:hover, .btn-bd-primary:active {\n color: #fff;\n background-color: #7952b3;\n border-color: #7952b3;\n}\n\n.btn-bd-primary:focus {\n box-shadow: 0 0 0 3px rgba(121, 82, 179, 0.25);\n}\n\n.btn-bd-download {\n font-weight: 600;\n color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:hover, .btn-bd-download:active {\n color: #2a2730;\n background-color: #ffe484;\n border-color: #ffe484;\n}\n\n.btn-bd-download:focus {\n box-shadow: 0 0 0 3px rgba(255, 228, 132, 0.25);\n}\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n border-radius: 0.25rem;\n}\n\n.bd-callout h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n}\n\n.bd-callout p:last-child {\n margin-bottom: 0;\n}\n\n.bd-callout code {\n border-radius: 0.25rem;\n}\n\n.bd-callout + .bd-callout {\n margin-top: -.25rem;\n}\n\n.bd-callout-info {\n border-left-color: #5bc0de;\n}\n\n.bd-callout-info h4 {\n color: #5bc0de;\n}\n\n.bd-callout-warning {\n border-left-color: #f0ad4e;\n}\n\n.bd-callout-warning h4 {\n color: #f0ad4e;\n}\n\n.bd-callout-danger {\n border-left-color: #d9534f;\n}\n\n.bd-callout-danger h4 {\n color: #d9534f;\n}\n\n.bd-browser-bugs td p {\n margin-bottom: 0;\n}\n\n.bd-browser-bugs th:first-child {\n width: 18%;\n}\n\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: #563d7c;\n background-color: #f9f9f9;\n border-radius: 0.25rem;\n}\n\n.bd-brand-logos .inverse {\n color: #fff;\n background-color: #563d7c;\n}\n\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n}\n\n.bd-brand-item + .bd-brand-item {\n border-top: 1px solid #fff;\n}\n\n.bd-brand-item h1,\n.bd-brand-item h3 {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n@media (min-width: 768px) {\n .bd-brand-item {\n display: table-cell;\n width: 1%;\n }\n .bd-brand-item + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid #fff;\n }\n .bd-brand-item h1 {\n font-size: 4rem;\n }\n}\n\n@media (min-width: 768px) and (max-width: 1200px) {\n .bd-brand-item h1 {\n font-size: calc(1.525rem + 3.3vw) ;\n }\n}\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden;\n}\n\n.color-swatches .bd-purple {\n background-color: #563d7c;\n}\n\n.color-swatches .bd-purple-light {\n background-color: #cbbde2;\n}\n\n.color-swatches .bd-purple-lighter {\n background-color: #e5e1ea;\n}\n\n.color-swatches .bd-gray {\n background-color: #f9f9f9;\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n border-radius: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .color-swatch {\n width: 6rem;\n height: 6rem;\n }\n}\n\n.swatch-blue {\n color: #fff;\n background-color: #007bff;\n}\n\n.swatch-indigo {\n color: #fff;\n background-color: #6610f2;\n}\n\n.swatch-purple {\n color: #fff;\n background-color: #6f42c1;\n}\n\n.swatch-pink {\n color: #fff;\n background-color: #e83e8c;\n}\n\n.swatch-red {\n color: #fff;\n background-color: #dc3545;\n}\n\n.swatch-orange {\n color: #212529;\n background-color: #fd7e14;\n}\n\n.swatch-yellow {\n color: #212529;\n background-color: #ffc107;\n}\n\n.swatch-green {\n color: #fff;\n background-color: #28a745;\n}\n\n.swatch-teal {\n color: #fff;\n background-color: #20c997;\n}\n\n.swatch-cyan {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.swatch-white {\n color: #212529;\n background-color: #fff;\n}\n\n.swatch-gray {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-gray-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-primary {\n color: #fff;\n background-color: #007bff;\n}\n\n.swatch-secondary {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-success {\n color: #fff;\n background-color: #28a745;\n}\n\n.swatch-info {\n color: #fff;\n background-color: #17a2b8;\n}\n\n.swatch-warning {\n color: #212529;\n background-color: #ffc107;\n}\n\n.swatch-danger {\n color: #fff;\n background-color: #dc3545;\n}\n\n.swatch-light {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.swatch-dark {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-100 {\n color: #212529;\n background-color: #f8f9fa;\n}\n\n.swatch-200 {\n color: #212529;\n background-color: #e9ecef;\n}\n\n.swatch-300 {\n color: #212529;\n background-color: #dee2e6;\n}\n\n.swatch-400 {\n color: #212529;\n background-color: #ced4da;\n}\n\n.swatch-500 {\n color: #212529;\n background-color: #adb5bd;\n}\n\n.swatch-600 {\n color: #fff;\n background-color: #6c757d;\n}\n\n.swatch-700 {\n color: #fff;\n background-color: #495057;\n}\n\n.swatch-800 {\n color: #fff;\n background-color: #343a40;\n}\n\n.swatch-900 {\n color: #fff;\n background-color: #212529;\n}\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n}\n\n.bd-clipboard + .highlight {\n margin-top: 0;\n}\n\n@media (min-width: 768px) {\n .bd-clipboard {\n display: block;\n }\n}\n\n.btn-clipboard {\n position: absolute;\n top: .5rem;\n right: .5rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n font-size: 75%;\n color: #818a91;\n background-color: transparent;\n border: 0;\n border-radius: 0.25rem;\n}\n\n.btn-clipboard:hover {\n color: #fff;\n background-color: #027de7;\n}\n\n.bd-placeholder-img {\n font-size: 1.125rem;\n text-anchor: middle;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.bd-placeholder-img-lg {\n font-size: 3.5rem;\n}\n\n@media (max-width: 1200px) {\n .bd-placeholder-img-lg {\n font-size: calc(1.475rem + 2.7vw) ;\n }\n}\n\n.hll {\n background-color: #ffc;\n}\n\n.c {\n color: #999;\n}\n\n.k {\n color: #069;\n}\n\n.o {\n color: #555;\n}\n\n.cm {\n color: #999;\n}\n\n.cp {\n color: #099;\n}\n\n.c1 {\n color: #999;\n}\n\n.cs {\n color: #999;\n}\n\n.gd {\n background-color: #fcc;\n border: 1px solid #c00;\n}\n\n.ge {\n font-style: italic;\n}\n\n.gr {\n color: #f00;\n}\n\n.gh {\n color: #030;\n}\n\n.gi {\n background-color: #cfc;\n border: 1px solid #0c0;\n}\n\n.go {\n color: #aaa;\n}\n\n.gp {\n color: #009;\n}\n\n.gu {\n color: #030;\n}\n\n.gt {\n color: #9c6;\n}\n\n.kc {\n color: #069;\n}\n\n.kd {\n color: #069;\n}\n\n.kn {\n color: #069;\n}\n\n.kp {\n color: #069;\n}\n\n.kr {\n color: #069;\n}\n\n.kt {\n color: #078;\n}\n\n.m {\n color: #f60;\n}\n\n.s {\n color: #d44950;\n}\n\n.na {\n color: #4f9fcf;\n}\n\n.nb {\n color: #366;\n}\n\n.nc {\n color: #0a8;\n}\n\n.no {\n color: #360;\n}\n\n.nd {\n color: #99f;\n}\n\n.ni {\n color: #999;\n}\n\n.ne {\n color: #c00;\n}\n\n.nf {\n color: #c0f;\n}\n\n.nl {\n color: #99f;\n}\n\n.nn {\n color: #0cf;\n}\n\n.nt {\n color: #2f6f9f;\n}\n\n.nv {\n color: #033;\n}\n\n.ow {\n color: #000;\n}\n\n.w {\n color: #bbb;\n}\n\n.mf {\n color: #f60;\n}\n\n.mh {\n color: #f60;\n}\n\n.mi {\n color: #f60;\n}\n\n.mo {\n color: #f60;\n}\n\n.sb {\n color: #c30;\n}\n\n.sc {\n color: #c30;\n}\n\n.sd {\n font-style: italic;\n color: #c30;\n}\n\n.s2 {\n color: #c30;\n}\n\n.se {\n color: #c30;\n}\n\n.sh {\n color: #c30;\n}\n\n.si {\n color: #a00;\n}\n\n.sx {\n color: #c30;\n}\n\n.sr {\n color: #3aa;\n}\n\n.s1 {\n color: #c30;\n}\n\n.ss {\n color: #fc3;\n}\n\n.bp {\n color: #366;\n}\n\n.vc {\n color: #033;\n}\n\n.vg {\n color: #033;\n}\n\n.vi {\n color: #033;\n}\n\n.il {\n color: #f60;\n}\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt {\n color: #999;\n}\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.anchorjs-link {\n font-weight: 400;\n color: rgba(0, 123, 255, 0.5);\n transition: color 0.15s ease-in-out, opacity 0.15s ease-in-out;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .anchorjs-link {\n transition: none;\n }\n}\n\n.anchorjs-link:hover {\n color: #007bff;\n text-decoration: none;\n}\n\n.algolia-autocomplete {\n display: block !important;\n -ms-flex: 1;\n flex: 1;\n}\n\n.algolia-autocomplete .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175);\n}\n\n@media (min-width: 768px) {\n .algolia-autocomplete .ds-dropdown-menu {\n width: 175%;\n }\n}\n\n.algolia-autocomplete .ds-dropdown-menu::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n}\n\n.algolia-autocomplete .ds-dropdown-menu .ds-suggestions {\n margin-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n font-size: 0.875rem !important;\n font-weight: 600 !important;\n color: #7952b3 !important;\n border-bottom: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline {\n display: block !important;\n font-size: 0.875rem;\n color: #495057;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline::after {\n padding: 0 .25rem;\n content: \"/\";\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n float: none !important;\n width: 100% !important;\n padding: .25rem 1rem !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--content::before {\n display: none !important;\n}\n\n.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--title {\n display: block;\n margin-bottom: 0 !important;\n font-size: 0.875rem !important;\n font-weight: 400 !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text {\n -ms-flex: 0 0 100%;\n flex: 0 0 100%;\n max-width: 100%;\n padding: .2rem 0;\n font-size: 0.8125rem !important;\n font-weight: 400;\n line-height: 1.25 !important;\n color: #6c757d;\n}\n\n.algolia-autocomplete .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n font-size: 0.75rem !important;\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.algolia-autocomplete .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, 0.12);\n}\n\n.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, 0.5) !important;\n}\n\n.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, 0.15) !important;\n}\n/*# sourceMappingURL=docs.min.css.map */",".skippy {\n display: block;\n padding: 1em;\n color: $white;\n text-align: center;\n background-color: $bd-purple;\n outline: 0;\n\n @include hover {\n color: $white;\n }\n}\n\n.skippy-text {\n padding: .5em;\n outline: 1px dotted;\n}\n","// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Originally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS-an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular pseudo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n","// stylelint-disable declaration-no-important\n\n//\n// Right side table of contents\n//\n\n.bd-toc {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n height: calc(100vh - 4rem);\n overflow-y: auto;\n }\n order: 2;\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n @include font-size(.875rem);\n}\n\n.section-nav {\n padding-left: 0;\n border-left: 1px solid #eee;\n\n ul {\n padding-left: 1rem;\n }\n}\n\n.toc-entry {\n display: block;\n\n a {\n display: block;\n padding: .125rem 1.5rem;\n color: #77757a;\n\n &:hover {\n color: $blue;\n text-decoration: none;\n }\n }\n}\n\n//\n// Left side navigation\n//\n\n.bd-sidebar {\n order: 0;\n // background-color: #f5f2f9;\n border-bottom: 1px solid rgba(0, 0, 0, .1);\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n position: sticky;\n top: 4rem;\n z-index: 1000;\n height: calc(100vh - 4rem);\n }\n border-right: 1px solid rgba(0, 0, 0, .1);\n }\n\n @include media-breakpoint-up(xl) {\n flex: 0 1 320px;\n }\n}\n\n.bd-links {\n padding-top: 1rem;\n padding-bottom: 1rem;\n margin-right: -15px;\n margin-left: -15px;\n\n @include media-breakpoint-up(md) {\n @supports (position: sticky) {\n max-height: calc(100vh - 9rem);\n overflow-y: auto;\n }\n }\n\n // Override collapse behaviors\n @include media-breakpoint-up(md) {\n display: block !important;\n }\n}\n\n.bd-search {\n position: relative; // To contain the Algolia search\n padding: 1rem 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-bottom: 1px solid rgba(0, 0, 0, .05);\n\n .form-control:focus {\n border-color: $bd-purple-bright;\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.bd-search-docs-toggle {\n line-height: 1;\n color: $gray-900;\n}\n\n.bd-sidenav {\n display: none;\n}\n\n.bd-toc-link {\n display: block;\n padding: .25rem 1.5rem;\n font-weight: 600;\n color: rgba(0, 0, 0, .65);\n\n &:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n }\n}\n\n.bd-toc-item {\n &.active {\n margin-bottom: 1rem;\n\n &:not(:first-child) {\n margin-top: 1rem;\n }\n\n > .bd-toc-link {\n color: rgba(0, 0, 0, .85);\n\n &:hover {\n background-color: transparent;\n }\n }\n\n > .bd-sidenav {\n display: block;\n }\n }\n}\n\n// All levels of nav\n.bd-sidebar .nav > li > a {\n display: block;\n padding: .25rem 1.5rem;\n @include font-size(90%);\n color: rgba(0, 0, 0, .65);\n}\n\n.bd-sidebar .nav > li > a:hover {\n color: rgba(0, 0, 0, .85);\n text-decoration: none;\n background-color: transparent;\n}\n\n.bd-sidebar .nav > .active > a,\n.bd-sidebar .nav > .active:hover > a {\n font-weight: 600;\n color: rgba(0, 0, 0, .85);\n background-color: transparent;\n}\n","//\n// Footer\n//\n\n.bd-footer {\n @include font-size(.875rem);\n text-align: center;\n background-color: #f7f7f7;\n\n a {\n font-weight: 600;\n color: $gray-700;\n\n &:hover,\n &:focus {\n color: $link-color;\n }\n }\n\n p {\n margin-bottom: 0;\n }\n\n @include media-breakpoint-up(sm) {\n text-align: left;\n }\n}\n\n.bd-footer-links {\n padding-left: 0;\n margin-bottom: 1rem;\n\n li {\n display: inline-block;\n\n + li {\n margin-left: 1rem;\n }\n }\n}\n","// stylelint-disable no-duplicate-selectors, selector-no-qualifying-type\n\n//\n// Grid examples\n//\n\n.bd-example-row {\n .row {\n > .col,\n > [class^=\"col-\"] {\n padding-top: .75rem;\n padding-bottom: .75rem;\n background-color: rgba(86, 61, 124, .15);\n border: 1px solid rgba(86, 61, 124, .2);\n }\n }\n\n .row + .row {\n margin-top: 1rem;\n }\n\n .flex-items-top,\n .flex-items-middle,\n .flex-items-bottom {\n min-height: 6rem;\n background-color: rgba(255, 0, 0, .1);\n }\n}\n\n.bd-example-row-flex-cols .row {\n min-height: 10rem;\n background-color: rgba(255, 0, 0, .1);\n}\n\n.bd-highlight {\n background-color: rgba($bd-purple, .15);\n border: 1px solid rgba($bd-purple, .15);\n}\n\n// Grid mixins\n.example-container {\n width: 800px;\n @include make-container();\n}\n\n.example-row {\n @include make-row();\n}\n\n.example-content-main {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(8);\n }\n}\n\n.example-content-secondary {\n @include make-col-ready();\n\n @include media-breakpoint-up(sm) {\n @include make-col(6);\n }\n\n @include media-breakpoint-up(lg) {\n @include make-col(4);\n }\n}\n\n\n//\n// Container illustrations\n//\n\n.bd-example-container {\n min-width: 16rem;\n max-width: 25rem;\n margin-right: auto;\n margin-left: auto;\n}\n\n.bd-example-container-header {\n height: 3rem;\n margin-bottom: .5rem;\n background-color: lighten($blue, 50%);\n @include border-radius;\n}\n\n.bd-example-container-sidebar {\n float: right;\n width: 4rem;\n height: 8rem;\n background-color: lighten($blue, 25%);\n @include border-radius;\n}\n\n.bd-example-container-body {\n height: 8rem;\n margin-right: 4.5rem;\n background-color: lighten($bd-purple, 25%);\n @include border-radius;\n}\n\n.bd-example-container-fluid {\n max-width: none;\n}\n\n\n//\n// Docs examples\n//\n\n.bd-example {\n position: relative;\n padding: 1rem;\n margin: 1rem (-$grid-gutter-width / 2) 0;\n border: solid $gray-100;\n border-width: .2rem 0 0;\n @include clearfix();\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n margin-right: 0;\n margin-left: 0;\n border-width: .2rem;\n }\n\n + .highlight,\n + .clipboard + .highlight {\n margin-top: 0;\n }\n\n + p {\n margin-top: 2rem;\n }\n\n .pos-f-t {\n position: relative;\n margin: -1rem;\n\n @include media-breakpoint-up(sm) {\n margin: -1.5rem;\n }\n }\n\n .custom-file-input:lang(es) ~ .custom-file-label::after {\n content: \"Elegir\";\n }\n\n > .form-control {\n + .form-control {\n margin-top: .5rem;\n }\n }\n\n > .nav + .nav,\n > .alert + .alert,\n > .navbar + .navbar,\n > .progress + .progress,\n > .progress + .btn {\n margin-top: 1rem;\n }\n\n > .dropdown-menu:first-child {\n position: static;\n display: block;\n }\n\n > .form-group:last-child {\n margin-bottom: 0;\n }\n\n > .close {\n float: none;\n }\n}\n\n// Typography\n.bd-example-type {\n .table {\n td {\n padding: 1rem 0;\n border-color: #eee;\n }\n tr:first-child td {\n border-top: 0;\n }\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n margin-top: 0;\n margin-bottom: 0;\n }\n}\n\n// Contextual background colors\n.bd-example-bg-classes p {\n padding: 1rem;\n}\n\n// Images\n.bd-example {\n > svg + svg,\n > img + img {\n margin-left: .5rem;\n }\n}\n\n// Buttons\n.bd-example {\n > .btn,\n > .btn-group {\n margin-top: .25rem;\n margin-bottom: .25rem;\n }\n > .btn-toolbar + .btn-toolbar {\n margin-top: .5rem;\n }\n}\n\n// Forms\n.bd-example-control-sizing select,\n.bd-example-control-sizing input[type=\"text\"] + input[type=\"text\"] {\n margin-top: .5rem;\n}\n.bd-example-form .input-group {\n margin-bottom: .5rem;\n}\n.bd-example > textarea.form-control {\n resize: vertical;\n}\n\n// List groups\n.bd-example > .list-group {\n max-width: 400px;\n}\n.bd-example > [class*=\"list-group-horizontal\"] {\n max-width: 100%;\n}\n\n// Navbars\n.bd-example {\n .fixed-top,\n .sticky-top {\n position: static;\n margin: -1rem -1rem 1rem;\n }\n .fixed-bottom {\n position: static;\n margin: 1rem -1rem -1rem;\n }\n\n @include media-breakpoint-up(sm) {\n .fixed-top,\n .sticky-top {\n margin: -1.5rem -1.5rem 1rem;\n }\n .fixed-bottom {\n margin: 1rem -1.5rem -1.5rem;\n }\n }\n}\n\n// Pagination\n.bd-example .pagination {\n margin-top: .5rem;\n margin-bottom: .5rem;\n}\n\n// Example modals\n.modal {\n z-index: 1072;\n\n .tooltip,\n .popover {\n z-index: 1073;\n }\n}\n\n.modal-backdrop {\n z-index: 1071;\n}\n\n.bd-example-modal {\n background-color: #fafafa;\n\n .modal {\n position: relative;\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n z-index: 1;\n display: block;\n }\n\n .modal-dialog {\n left: auto;\n margin-right: auto;\n margin-left: auto;\n }\n}\n\n// Example tabbable tabs\n.bd-example-tabs .nav-tabs {\n margin-bottom: 1rem;\n}\n\n// Popovers\n.bd-example-popover-static {\n padding-bottom: 1.5rem;\n background-color: #f9f9f9;\n\n .popover {\n position: relative;\n display: block;\n float: left;\n width: 260px;\n margin: 1.25rem;\n }\n}\n\n// Tooltips\n.tooltip-demo a {\n white-space: nowrap;\n}\n\n.bd-example-tooltip-static .tooltip {\n position: relative;\n display: inline-block;\n margin: 10px 20px;\n opacity: 1;\n}\n\n// Scrollspy demo on fixed height div\n.scrollspy-example {\n position: relative;\n height: 200px;\n margin-top: .5rem;\n overflow: auto;\n}\n\n.scrollspy-example-2 {\n position: relative;\n height: 350px;\n overflow: auto;\n}\n\n.bd-example-border-utils {\n [class^=\"border\"] {\n display: inline-block;\n width: 5rem;\n height: 5rem;\n margin: .25rem;\n background-color: #f5f5f5;\n }\n}\n\n.bd-example-border-utils-0 {\n [class^=\"border\"] {\n border: 1px solid $border-color;\n }\n}\n\n//\n// Code snippets\n//\n\n.highlight {\n padding: 1rem;\n margin-top: 1rem;\n margin-bottom: 1rem;\n background-color: $gray-100;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n\n @include media-breakpoint-up(sm) {\n padding: 1.5rem;\n }\n}\n\n.bd-content .highlight {\n margin-right: (-$grid-gutter-width / 2);\n margin-left: (-$grid-gutter-width / 2);\n\n @include media-breakpoint-up(sm) {\n margin-right: 0;\n margin-left: 0;\n }\n}\n\n.highlight {\n pre {\n padding: 0;\n margin-top: 0;\n margin-bottom: 0;\n background-color: transparent;\n border: 0;\n }\n pre code {\n @include font-size(inherit);\n color: $gray-900; // Effectively the base text color\n }\n}\n","/// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-container($gutter: $grid-gutter-width) {\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n margin-right: auto;\n margin-left: auto;\n}\n\n\n// For each breakpoint, define the maximum width of the container in a media query\n@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {\n @each $breakpoint, $container-max-width in $max-widths {\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n max-width: $container-max-width;\n }\n }\n}\n\n@mixin make-row($gutter: $grid-gutter-width) {\n display: flex;\n flex-wrap: wrap;\n margin-right: -$gutter / 2;\n margin-left: -$gutter / 2;\n}\n\n@mixin make-col-ready($gutter: $grid-gutter-width) {\n position: relative;\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we use `flex` values\n // later on to override this initial width.\n width: 100%;\n padding-right: $gutter / 2;\n padding-left: $gutter / 2;\n}\n\n@mixin make-col($size, $columns: $grid-columns) {\n flex: 0 0 percentage($size / $columns);\n // Add a `max-width` to ensure content within each column does not blow out\n // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari\n // do not appear to require this.\n max-width: percentage($size / $columns);\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: $size / $columns;\n margin-left: if($num == 0, 0, percentage($num));\n}\n","@mixin clearfix() {\n &::after {\n display: block;\n clear: both;\n content: \"\";\n }\n}\n","// Buttons\n//\n// Custom buttons for the docs.\n\n.btn-bd-primary {\n font-weight: 600;\n color: $bd-purple-bright;\n border-color: $bd-purple-bright;\n\n &:hover,\n &:active {\n color: $white;\n background-color: $bd-purple-bright;\n border-color: $bd-purple-bright;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);\n }\n}\n\n.btn-bd-download {\n font-weight: 600;\n color: $bd-download;\n border-color: $bd-download;\n\n &:hover,\n &:active {\n color: $bd-dark;\n background-color: $bd-download;\n border-color: $bd-download;\n }\n\n &:focus {\n box-shadow: 0 0 0 3px rgba($bd-download, .25);\n }\n}\n","//\n// Callouts\n//\n\n.bd-callout {\n padding: 1.25rem;\n margin-top: 1.25rem;\n margin-bottom: 1.25rem;\n border: 1px solid #eee;\n border-left-width: .25rem;\n @include border-radius;\n\n h4 {\n margin-top: 0;\n margin-bottom: .25rem;\n }\n\n p:last-child {\n margin-bottom: 0;\n }\n\n code {\n @include border-radius;\n }\n\n + .bd-callout {\n margin-top: -.25rem;\n }\n}\n\n// Variations\n@mixin bs-callout-variant($color) {\n border-left-color: $color;\n\n h4 { color: $color; }\n}\n\n.bd-callout-info { @include bs-callout-variant($bd-info); }\n.bd-callout-warning { @include bs-callout-variant($bd-warning); }\n.bd-callout-danger { @include bs-callout-variant($bd-danger); }\n","// Wall of Browser Bugs\n//\n// Better display for the responsive table on the Wall of Browser Bugs.\n\n.bd-browser-bugs {\n td p {\n margin-bottom: 0;\n }\n th:first-child {\n width: 18%;\n }\n}\n","//\n// Brand guidelines\n//\n\n// Logo series wrapper\n.bd-brand-logos {\n display: table;\n width: 100%;\n margin-bottom: 1rem;\n overflow: hidden;\n color: $bd-purple;\n background-color: #f9f9f9;\n @include border-radius;\n\n .inverse {\n color: $white;\n background-color: $bd-purple;\n }\n}\n\n// Individual items\n.bd-brand-item {\n padding: 4rem 0;\n text-align: center;\n\n + .bd-brand-item {\n border-top: 1px solid $white;\n }\n\n // Heading content within\n h1,\n h3 {\n margin-top: 0;\n margin-bottom: 0;\n }\n\n @include media-breakpoint-up(md) {\n display: table-cell;\n width: 1%;\n\n + .bd-brand-item {\n border-top: 0;\n border-left: 1px solid $white;\n }\n\n h1 {\n @include font-size(4rem);\n }\n }\n}\n\n\n//\n// Color swatches\n//\n\n.color-swatches {\n margin: 0 -5px;\n overflow: hidden; // clearfix\n\n // Docs colors\n .bd-purple {\n background-color: $bd-purple;\n }\n .bd-purple-light {\n background-color: $bd-purple-light;\n }\n .bd-purple-lighter {\n background-color: #e5e1ea;\n }\n .bd-gray {\n background-color: #f9f9f9;\n }\n}\n\n.color-swatch {\n float: left;\n width: 4rem;\n height: 4rem;\n margin-right: .25rem;\n margin-left: .25rem;\n @include border-radius;\n\n @include media-breakpoint-up(md) {\n width: 6rem;\n height: 6rem;\n }\n}\n","//\n// Docs color palette classes\n//\n\n@each $color, $value in $colors {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n\n@each $color, $value in $theme-colors {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n\n@each $color, $value in $grays {\n .swatch-#{$color} {\n color: color-yiq($value);\n background-color: #{$value};\n }\n}\n","// clipboard.js\n//\n// JS-based `Copy` buttons for code snippets.\n\n.bd-clipboard {\n position: relative;\n display: none;\n float: right;\n\n + .highlight {\n margin-top: 0;\n }\n\n @include media-breakpoint-up(md) {\n display: block;\n }\n}\n\n.btn-clipboard {\n position: absolute;\n top: .5rem;\n right: .5rem;\n z-index: 10;\n display: block;\n padding: .25rem .5rem;\n @include font-size(75%);\n color: #818a91;\n background-color: transparent;\n border: 0;\n @include border-radius;\n\n &:hover {\n color: $white;\n background-color: #027de7;\n }\n}\n","//\n// Placeholder svg used in the docs.\n//\n\n// Remember to update `site/_layouts/examples.html` too if this changes!\n\n.bd-placeholder-img {\n @include font-size(1.125rem);\n text-anchor: middle;\n user-select: none;\n}\n\n.bd-placeholder-img-lg {\n @include font-size(3.5rem);\n}\n","// stylelint-disable declaration-block-single-line-max-declarations, selector-class-pattern\n\n.hll { background-color: #ffc; }\n.c { color: #999; }\n.k { color: #069; }\n.o { color: #555; }\n.cm { color: #999; }\n.cp { color: #099; }\n.c1 { color: #999; }\n.cs { color: #999; }\n.gd { background-color: #fcc; border: 1px solid #c00; }\n.ge { font-style: italic; }\n.gr { color: #f00; }\n.gh { color: #030; }\n.gi { background-color: #cfc; border: 1px solid #0c0; }\n.go { color: #aaa; }\n.gp { color: #009; }\n.gu { color: #030; }\n.gt { color: #9c6; }\n.kc { color: #069; }\n.kd { color: #069; }\n.kn { color: #069; }\n.kp { color: #069; }\n.kr { color: #069; }\n.kt { color: #078; }\n.m { color: #f60; }\n.s { color: #d44950; }\n.na { color: #4f9fcf; }\n.nb { color: #366; }\n.nc { color: #0a8; }\n.no { color: #360; }\n.nd { color: #99f; }\n.ni { color: #999; }\n.ne { color: #c00; }\n.nf { color: #c0f; }\n.nl { color: #99f; }\n.nn { color: #0cf; }\n.nt { color: #2f6f9f; }\n.nv { color: #033; }\n.ow { color: #000; }\n.w { color: #bbb; }\n.mf { color: #f60; }\n.mh { color: #f60; }\n.mi { color: #f60; }\n.mo { color: #f60; }\n.sb { color: #c30; }\n.sc { color: #c30; }\n.sd { font-style: italic; color: #c30; }\n.s2 { color: #c30; }\n.se { color: #c30; }\n.sh { color: #c30; }\n.si { color: #a00; }\n.sx { color: #c30; }\n.sr { color: #3aa; }\n.s1 { color: #c30; }\n.ss { color: #fc3; }\n.bp { color: #366; }\n.vc { color: #033; }\n.vg { color: #033; }\n.vi { color: #033; }\n.il { color: #f60; }\n\n.css .o,\n.css .o + .nt,\n.css .nt + .nt { color: #999; }\n\n.language-bash::before,\n.language-sh::before {\n color: #009;\n content: \"$ \";\n user-select: none;\n}\n\n.language-powershell::before {\n color: #009;\n content: \"PM> \";\n user-select: none;\n}\n",".anchorjs-link {\n font-weight: 400;\n color: rgba($link-color, .5);\n @include transition(color .15s ease-in-out, opacity .15s ease-in-out);\n\n &:hover {\n color: $link-color;\n text-decoration: none;\n }\n}\n","// stylelint-disable property-blacklist\n@mixin transition($transition...) {\n @if $enable-transitions {\n @if length($transition) == 0 {\n transition: $transition-base;\n } @else {\n transition: $transition;\n }\n }\n\n @if $enable-prefers-reduced-motion-media-query {\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n }\n}\n","// stylelint-disable declaration-no-important\n\n// Docsearch overrides\n//\n// `!important` indicates overridden properties.\n.algolia-autocomplete {\n display: block !important;\n flex: 1;\n\n // Menu container\n .ds-dropdown-menu {\n width: 100%;\n min-width: 0 !important;\n max-width: none !important;\n padding: .75rem 0 !important;\n background-color: $white;\n background-clip: padding-box;\n border: 1px solid rgba(0, 0, 0, .1);\n box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175);\n\n @include media-breakpoint-up(md) {\n width: 175%;\n }\n\n // Caret\n &::before {\n display: none !important;\n }\n\n [class^=\"ds-dataset-\"] {\n padding: 0 !important;\n overflow: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n }\n\n .ds-suggestions {\n margin-top: 0 !important;\n }\n }\n\n .algolia-docsearch-suggestion {\n padding: 0 !important;\n overflow: visible !important;\n }\n\n .algolia-docsearch-suggestion--category-header {\n padding: .125rem 1rem !important;\n margin-top: 0 !important;\n @include font-size(.875rem, true);\n font-weight: 600 !important;\n color: $bd-purple-bright !important;\n border-bottom: 0 !important;\n }\n\n .algolia-docsearch-suggestion--wrapper {\n float: none !important;\n padding-top: 0 !important;\n }\n\n // Section header\n .algolia-docsearch-suggestion--subcategory-column {\n float: none !important;\n width: auto !important;\n padding: 0 !important;\n text-align: left !important;\n }\n\n .algolia-docsearch-suggestion--subcategory-inline {\n display: block !important;\n @include font-size(.875rem);\n color: $gray-700;\n\n &::after {\n padding: 0 .25rem;\n content: \"/\";\n }\n }\n\n .algolia-docsearch-suggestion--content {\n display: flex;\n flex-wrap: wrap;\n float: none !important;\n width: 100% !important;\n padding: .25rem 1rem !important;\n\n // Vertical divider between column header and content\n &::before {\n display: none !important;\n }\n }\n\n .ds-suggestion {\n &:not(:first-child) {\n .algolia-docsearch-suggestion--category-header {\n padding-top: .75rem !important;\n margin-top: .75rem !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n }\n\n .algolia-docsearch-suggestion--subcategory-column {\n display: none !important;\n }\n }\n\n .algolia-docsearch-suggestion--title {\n display: block;\n margin-bottom: 0 !important;\n @include font-size(.875rem, true);\n font-weight: 400 !important;\n }\n\n .algolia-docsearch-suggestion--text {\n flex: 0 0 100%;\n max-width: 100%;\n padding: .2rem 0;\n @include font-size(.8125rem, true);\n font-weight: 400;\n line-height: 1.25 !important;\n color: $gray-600;\n }\n\n .algolia-docsearch-footer {\n float: none !important;\n width: auto !important;\n height: auto !important;\n padding: .75rem 1rem 0;\n @include font-size(.75rem, true);\n line-height: 1 !important;\n color: #767676 !important;\n border-top: 1px solid rgba(0, 0, 0, .1);\n }\n\n .algolia-docsearch-footer--logo {\n display: inline !important;\n overflow: visible !important;\n color: inherit !important;\n text-indent: 0 !important;\n background: none !important;\n }\n\n .algolia-docsearch-suggestion--highlight {\n color: #5f2dab;\n background-color: rgba(154, 132, 187, .12);\n }\n\n .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight {\n box-shadow: inset 0 -2px 0 0 rgba(95, 45, 171, .5) !important;\n }\n\n .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content {\n background-color: rgba(208, 189, 236, .15) !important;\n }\n}\n"]} \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/bootstrap-themes.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/bootstrap-themes.png new file mode 100644 index 000000000..15f33f3f7 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/bootstrap-themes.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/bootstrap-themes.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/bootstrap-themes@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/bootstrap-themes.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/bootstrap-themes@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/album.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/album.png new file mode 100644 index 000000000..694b3b2d2 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/album.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/album.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/album@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/album.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/album@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/blog.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/blog.png new file mode 100644 index 000000000..6d6c8356b Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/blog.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/blog.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/blog@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/blog.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/blog@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/carousel.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/carousel.png new file mode 100644 index 000000000..abca5b3db Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/carousel.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/carousel.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/carousel@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/carousel.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/carousel@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/checkout.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/checkout.png new file mode 100644 index 000000000..7af2e2efa Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/checkout.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/checkout.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/checkout@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/checkout.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/checkout@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/cover.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/cover.png new file mode 100644 index 000000000..5458ff11d Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/cover.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/cover.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/cover@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/cover.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/cover@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/dashboard.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/dashboard.png new file mode 100644 index 000000000..1ef0c3925 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/dashboard.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/dashboard.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/dashboard@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/dashboard.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/dashboard@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/floating-labels.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/floating-labels.png new file mode 100644 index 000000000..c836eadbb Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/floating-labels.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/floating-labels.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/floating-labels@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/floating-labels.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/floating-labels@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid.png new file mode 100644 index 000000000..b3b5b3565 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid@2x.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid@2x.png new file mode 100644 index 000000000..e95c36365 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/grid@2x.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/jumbotron.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/jumbotron.png new file mode 100644 index 000000000..afca61a7c Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/jumbotron.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/jumbotron.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/jumbotron@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/jumbotron.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/jumbotron@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-bottom.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-bottom.png new file mode 100644 index 000000000..e9f0abc95 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-bottom.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-bottom.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-bottom@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-bottom.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-bottom@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-fixed.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-fixed.png new file mode 100644 index 000000000..c839602a7 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-fixed.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-fixed.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-fixed@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-fixed.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-fixed@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-static.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-static.png new file mode 100644 index 000000000..faebe3451 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-static.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-static.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-static@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbar-static.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbar-static@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbars.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbars.png new file mode 100644 index 000000000..874f6d752 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbars.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbars.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbars@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/navbars.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/navbars@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/offcanvas.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/offcanvas.png new file mode 100644 index 000000000..b5073eba4 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/offcanvas.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/offcanvas.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/offcanvas@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/offcanvas.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/offcanvas@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/pricing.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/pricing.png new file mode 100644 index 000000000..3638c9ef3 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/pricing.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/pricing.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/pricing@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/pricing.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/pricing@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/product.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/product.png new file mode 100644 index 000000000..a8d3dcb8d Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/product.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/product.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/product@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/product.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/product@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sign-in.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sign-in.png new file mode 100644 index 000000000..53aed9724 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sign-in.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sign-in.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sign-in@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sign-in.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sign-in@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/starter-template.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/starter-template.png new file mode 100644 index 000000000..0cbcaa1eb Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/starter-template.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/starter-template.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/starter-template@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/starter-template.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/starter-template@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer-navbar.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer-navbar.png new file mode 100644 index 000000000..f64d66638 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer-navbar.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sticky-footer-navbar.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer-navbar@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sticky-footer-navbar.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer-navbar@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer.png new file mode 100644 index 000000000..203ed62f5 Binary files /dev/null and b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer.png differ diff --git a/vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sticky-footer.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer@2x.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/examples/screenshots/sticky-footer.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/examples/sticky-footer@2x.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/android-chrome-192x192.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/android-chrome-192x192.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/android-chrome-192x192.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/android-chrome-192x192.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/android-chrome-512x512.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/android-chrome-512x512.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/android-chrome-512x512.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/android-chrome-512x512.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/apple-touch-icon.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/apple-touch-icon.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/apple-touch-icon.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/apple-touch-icon.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/browserconfig.xml b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/browserconfig.xml new file mode 100644 index 000000000..0d17d11d4 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/browserconfig.xml @@ -0,0 +1,11 @@ +--- +--- + + + + + + #563d7c + + + diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/favicon-16x16.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/favicon-16x16.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/favicon-16x16.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/favicon-16x16.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/favicon-32x32.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/favicon-32x32.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/favicon-32x32.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/favicon-32x32.png diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/manifest.json b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/manifest.json new file mode 100644 index 000000000..a92accba6 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/manifest.json @@ -0,0 +1,22 @@ +--- +--- +{ + "name": "Bootstrap", + "short_name": "Bootstrap", + "icons": [ + { + "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "{{ site.baseurl }}/docs/{{ site.docs_version }}/assets/img/favicons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": "/?utm_source=a2hs", + "theme_color": "#563d7c", + "background_color": "#563d7c", + "display": "standalone" +} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-144x144.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-144x144.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-144x144.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-144x144.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-150x150.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-150x150.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-150x150.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-150x150.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-310x150.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-310x150.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-310x150.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-310x150.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-310x310.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-310x310.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-310x310.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-310x310.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-70x70.png b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-70x70.png similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/mstile-70x70.png rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/mstile-70x70.png diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/safari-pinned-tab.svg b/vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/safari-pinned-tab.svg similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/img/favicons/safari-pinned-tab.svg rename to vendor/twbs/bootstrap/site/docs/4.3/assets/img/favicons/safari-pinned-tab.svg diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/js/docs.min.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/docs.min.js new file mode 100644 index 000000000..8f0874459 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/docs.min.js @@ -0,0 +1,22 @@ +!function(t,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(t.AnchorJS=e(),t.anchors=new t.AnchorJS)}(this,function(){"use strict";return function(t){function h(t){t.icon=t.hasOwnProperty("icon")?t.icon:"",t.visible=t.hasOwnProperty("visible")?t.visible:"hover",t.placement=t.hasOwnProperty("placement")?t.placement:"right",t.ariaLabel=t.hasOwnProperty("ariaLabel")?t.ariaLabel:"Anchor",t.class=t.hasOwnProperty("class")?t.class:"",t.truncate=t.hasOwnProperty("truncate")?Math.floor(t.truncate):64}function d(t){var e;if("string"==typeof t||t instanceof String)e=[].slice.call(document.querySelectorAll(t));else{if(!(Array.isArray(t)||t instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(t)}return e}this.options=t||{},this.elements=[],h(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(t){var e,n,o,i,r,A,a,l,c,s,u,f=[];if(h(this.options),"touch"===(u=this.options.visible)&&(u=this.isTouchDevice()?"always":"hover"),t||(t="h2, h3, h4, h5, h6"),0===(e=d(t)).length)return this;for(function(){if(null===document.head.querySelector("style.anchorjs")){var t,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(t=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,t),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}(),n=document.querySelectorAll("[id]"),o=[].map.call(n,function(t){return t.id}),r=0;r\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(t){var e=t.firstChild&&-1<(" "+t.firstChild.className+" ").indexOf(" anchorjs-link "),n=t.lastChild&&-1<(" "+t.lastChild.className+" ").indexOf(" anchorjs-link ");return e||n||!1}}}); +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function i(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,i),e.l=!0,e.exports}return i.m=n,i.c=o,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)i.d(n,o,function(t){return e[t]}.bind(null,o));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,n){"use strict";var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(){function o(t,e){for(var n=0;n + * Licensed under MIT (https://github.com/Johann-S/bs-custom-file-input/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.bsCustomFileInput=e()}(this,function(){"use strict";var f={CUSTOMFILE:'.custom-file input[type="file"]',CUSTOMFILELABEL:".custom-file-label",FORM:"form",INPUT:"input"},o=function(t){if(0 h2, .bd-content > h3, .bd-content > h4, .bd-content > h5");i(".bd-content").children("h2, h3, h4, h5").wrapInner('');bsCustomFileInput.init()})})(jQuery);(function(){"use strict";function t(){var t=/MSIE ([0-9.]+)/.exec(window.navigator.userAgent);if(t===null){return null}var e=parseInt(t[1],10);var n=Math.floor(e);return n}function e(){var t=new Function("/*@cc_on return @_jscript_version; @*/")();if(typeof t==="undefined"){return 11}if(t<9){return 8}return t}var n=window.navigator.userAgent;if(n.indexOf("Opera")>-1||n.indexOf("Presto")>-1){return}var o=t();if(o===null){return}var i=e();if(o!==i){window.alert("WARNING: You appear to be using IE"+i+" in IE"+o+" emulation mode.\nIE emulation modes can behave significantly differently from ACTUAL older versions of IE.\nPLEASE DON'T FILE BOOTSTRAP BUGS based on testing in IE emulation modes!")}})();(function(){"use strict";if(!window.docsearch){return}var t=document.getElementById("search-input");var e=t.getAttribute("data-docs-version");function o(){var t=window.location;var e=t.origin;if(!e){var n=t.port?":"+t.port:"";e=t.protocol+"//"+t.hostname+n}return e}window.docsearch({apiKey:"5990ad008512000bba2cf951ccf0332f",indexName:"bootstrap",inputSelector:"#search-input",algoliaOptions:{facetFilters:["version:"+e]},transformData:function(t){return t.map(function(t){var e=o();var n=/^https?:\/\/getbootstrap\.com/;t.url=e.match(n)?t.url:t.url.replace(n,"");if(t.anchor==="content"){t.url=t.url.replace(/#content$/,"");t.anchor=null}return t})},debug:false})})(); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/application.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/application.js similarity index 83% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/application.js rename to vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/application.js index 7666da065..863af6828 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/application.js +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/application.js @@ -4,13 +4,13 @@ /*! * JavaScript for Bootstrap's docs (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. For - * details, see https://creativecommons.org/licenses/by/3.0/. + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the Creative Commons Attribution 3.0 Unported License. + * For details, see https://creativecommons.org/licenses/by/3.0/. */ -/* global ClipboardJS: false, anchors: false, Holder: false */ +/* global ClipboardJS: false, anchors: false, bsCustomFileInput: false */ (function ($) { 'use strict' @@ -24,6 +24,12 @@ $('[data-toggle="popover"]').popover() + $('.toast') + .toast({ + autohide: false + }) + .toast('show') + // Demos within modals $('.tooltip-test').tooltip() $('.popover-test').popover() @@ -54,7 +60,7 @@ // Insert copy to clipboard button before .highlight $('figure.highlight, div.highlight').each(function () { - var btnHtml = '
' + var btnHtml = '
' $(this).before(btnHtml) $('.btn-clipboard') .tooltip() @@ -99,14 +105,8 @@ icon: '#' } anchors.add('.bd-content > h2, .bd-content > h3, .bd-content > h4, .bd-content > h5') - $('.bd-content > h2, .bd-content > h3, .bd-content > h4, .bd-content > h5').wrapInner('
') + $('.bd-content').children('h2, h3, h4, h5').wrapInner('') - // Holder - Holder.addTheme('gray', { - bg: '#777', - fg: 'rgba(255,255,255,.75)', - font: 'Helvetica', - fontweight: 'normal' - }) + bsCustomFileInput.init() }) }(jQuery)) diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/ie-emulation-modes-warning.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/ie-emulation-modes-warning.js similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/ie-emulation-modes-warning.js rename to vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/ie-emulation-modes-warning.js diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/search.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/search.js similarity index 67% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/search.js rename to vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/search.js index 2e91fcf21..459d412df 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/js/src/search.js +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/src/search.js @@ -12,6 +12,19 @@ var inputElement = document.getElementById('search-input') var siteDocsVersion = inputElement.getAttribute('data-docs-version') + function getOrigin() { + var location = window.location + var origin = location.origin + + if (!origin) { + var port = location.port ? ':' + location.port : '' + + origin = location.protocol + '//' + location.hostname + port + } + + return origin + } + window.docsearch({ apiKey: '5990ad008512000bba2cf951ccf0332f', indexName: 'bootstrap', @@ -19,21 +32,21 @@ algoliaOptions: { facetFilters: ['version:' + siteDocsVersion] }, - handleSelected: function (input, event, suggestion) { - var url = suggestion.url - url = suggestion.isLvl1 ? url.split('#')[0] : url - // If it's a title we remove the anchor so it does not jump. - window.location.href = url - }, transformData: function (hits) { return hits.map(function (hit) { - // When in production, return the result as is, - // otherwise remove our url from it. - var siteurl = inputElement.getAttribute('data-siteurl') + var siteurl = getOrigin() var urlRE = /^https?:\/\/getbootstrap\.com/ + // When in production, return the result as is, + // otherwise remove our url from it. hit.url = siteurl.match(urlRE) ? hit.url : hit.url.replace(urlRE, '') + // Prevent jumping to first header + if (hit.anchor === 'content') { + hit.url = hit.url.replace(/#content$/, '') + hit.anchor = null + } + return hit }) }, diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/anchor.min.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/anchor.min.js new file mode 100644 index 000000000..29a64acae --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/anchor.min.js @@ -0,0 +1,6 @@ +/** + * AnchorJS - v4.1.1 - 2018-07-01 + * https://github.com/bryanbraun/anchorjs + * Copyright (c) 2018 Bryan Braun; Licensed MIT + */ +!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function d(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64}function f(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],d(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var e,t,i,n,o,s,r,a,c,h,l,u=[];if(d(this.options),"touch"===(l=this.options.visible)&&(l=this.isTouchDevice()?"always":"hover"),A||(A="h2, h3, h4, h5, h6"),0===(e=f(A)).length)return this;for(function(){if(null===document.head.querySelector("style.anchorjs")){var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}(),t=document.querySelectorAll("[id]"),i=[].map.call(t,function(A){return A.id}),o=0;o\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),t=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||t||!1}}}); \ No newline at end of file diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/bs-custom-file-input.min.js b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/bs-custom-file-input.min.js new file mode 100644 index 000000000..bdf702491 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/js/vendor/bs-custom-file-input.min.js @@ -0,0 +1,7 @@ +/*! + * bsCustomFileInput v1.3.1 (https://github.com/Johann-S/bs-custom-file-input) + * Copyright 2018 Johann-S + * Licensed under MIT (https://github.com/Johann-S/bs-custom-file-input/blob/master/LICENSE) + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.bsCustomFileInput=t()}(this,function(){"use strict";var d={CUSTOMFILE:'.custom-file input[type="file"]',CUSTOMFILELABEL:".custom-file-label",FORM:"form",INPUT:"input"},r=function(e){if(0 img { - + img { +.bd-example { + > svg + svg, + > img + img { margin-left: .5rem; } } // Buttons .bd-example { + > .btn, > .btn-group { margin-top: .25rem; margin-bottom: .25rem; @@ -245,6 +243,9 @@ .bd-example > .list-group { max-width: 400px; } +.bd-example > [class*="list-group-horizontal"] { + max-width: 100%; +} // Navbars .bd-example { @@ -405,7 +406,7 @@ border: 0; } pre code { - font-size: inherit; + @include font-size(inherit); color: $gray-900; // Effectively the base text color } } diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_content.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_content.scss similarity index 82% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_content.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_content.scss index decb6c4c3..439601d1e 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_content.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_content.scss @@ -13,16 +13,10 @@ > h4[id] { pointer-events: none; - > div, - > a { - pointer-events: auto; - } - &::before { display: block; height: 6rem; margin-top: -6rem; - visibility: hidden; content: ""; } } @@ -35,7 +29,6 @@ @include media-breakpoint-down(md) { display: block; overflow-x: auto; - -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057 &.table-bordered { border: 0; @@ -67,11 +60,28 @@ } } +.bd-content-title { + display: block; + pointer-events: auto; +} + // // Docs sections // .bd-content { + > h2 { + @include font-size($h2-font-size); + } + + > h3 { + @include font-size($h3-font-size); + } + + > h4 { + @include font-size($h4-font-size); + } + > h2:not(:first-child) { margin-top: 3rem; } @@ -98,20 +108,15 @@ margin-top: 1rem; margin-bottom: .5rem; font-weight: 300; - - @include media-breakpoint-up(sm) { - font-size: 3rem; - } + @include font-size(3rem); } .bd-lead { - font-size: 1.125rem; + @include font-size(1.5rem); font-weight: 300; - @include media-breakpoint-up(sm) { + @include media-breakpoint-up(lg) { max-width: 80%; - margin-bottom: 1rem; - font-size: 1.5rem; } } diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_footer.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_footer.scss similarity index 88% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_footer.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_footer.scss index ab605d285..29d31df3a 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_footer.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_footer.scss @@ -3,12 +3,12 @@ // .bd-footer { - font-size: 85%; + @include font-size(.875rem); text-align: center; background-color: #f7f7f7; a { - font-weight: 500; + font-weight: 600; color: $gray-700; &:hover, diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_masthead.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_masthead.scss similarity index 88% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_masthead.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_masthead.scss index 0e3cea069..f4e70a2cf 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_masthead.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_masthead.scss @@ -6,14 +6,14 @@ // background-image: linear-gradient(45deg, #fafafa, #f5f5f5); h1 { + @include font-size(4rem); line-height: 1; } .btn { - width: 100%; padding: .8rem 2rem; - font-size: 1.25rem; - font-weight: 500; + font-weight: 600; + @include font-size(1.25rem); } .carbonad { @@ -31,10 +31,6 @@ } @include media-breakpoint-up(md) { - h1 { - font-size: 4rem; - } - .carbonad { margin-top: 3rem !important; } diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_nav.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_nav.scss similarity index 76% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_nav.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_nav.scss index 73c6bad64..c3fdc8e5f 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_nav.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_nav.scss @@ -16,7 +16,6 @@ height: 2.5rem; margin-top: .25rem; overflow: hidden; - font-size: .875rem; .navbar-nav { padding-bottom: 2rem; @@ -43,12 +42,12 @@ &.active, &:hover { - color: #fff; + color: $white; background-color: transparent; } &.active { - font-weight: 500; + font-weight: 600; } } } @@ -61,14 +60,14 @@ } .dropdown-menu { - font-size: .875rem; + @include font-size(.875rem); } .dropdown-item.active { - font-weight: 500; + font-weight: 600; color: $gray-900; background-color: transparent; - background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: .4rem .6rem; background-size: .75rem .75rem; diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_placeholder-img.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_placeholder-img.scss new file mode 100644 index 000000000..90a29544e --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_placeholder-img.scss @@ -0,0 +1,15 @@ +// +// Placeholder svg used in the docs. +// + +// Remember to update `site/_layouts/examples.html` too if this changes! + +.bd-placeholder-img { + @include font-size(1.125rem); + text-anchor: middle; + user-select: none; +} + +.bd-placeholder-img-lg { + @include font-size(3.5rem); +} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_sidebar.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_sidebar.scss similarity index 94% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_sidebar.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_sidebar.scss index 0cfbd60d2..b302b22fe 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_sidebar.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_sidebar.scss @@ -14,7 +14,7 @@ order: 2; padding-top: 1.5rem; padding-bottom: 1.5rem; - font-size: .875rem; + @include font-size(.875rem); } .section-nav { @@ -23,10 +23,6 @@ ul { padding-left: 1rem; - - ul { - display: none; - } } } @@ -36,7 +32,7 @@ a { display: block; padding: .125rem 1.5rem; - color: #99979c; + color: #77757a; &:hover { color: $blue; @@ -113,7 +109,7 @@ .bd-toc-link { display: block; padding: .25rem 1.5rem; - font-weight: 500; + font-weight: 600; color: rgba(0, 0, 0, .65); &:hover { @@ -148,7 +144,7 @@ .bd-sidebar .nav > li > a { display: block; padding: .25rem 1.5rem; - font-size: 90%; + @include font-size(90%); color: rgba(0, 0, 0, .65); } @@ -160,7 +156,7 @@ .bd-sidebar .nav > .active > a, .bd-sidebar .nav > .active:hover > a { - font-weight: 500; + font-weight: 600; color: rgba(0, 0, 0, .85); background-color: transparent; } diff --git a/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_skippy.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_skippy.scss new file mode 100644 index 000000000..db971d114 --- /dev/null +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_skippy.scss @@ -0,0 +1,17 @@ +.skippy { + display: block; + padding: 1em; + color: $white; + text-align: center; + background-color: $bd-purple; + outline: 0; + + @include hover { + color: $white; + } +} + +.skippy-text { + padding: .5em; + outline: 1px dotted; +} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_syntax.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_syntax.scss similarity index 98% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_syntax.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_syntax.scss index e66c5da22..c03e800f8 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_syntax.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_syntax.scss @@ -1,4 +1,4 @@ -// stylelint-disable declaration-block-single-line-max-declarations +// stylelint-disable declaration-block-single-line-max-declarations, selector-class-pattern .hll { background-color: #ffc; } .c { color: #999; } diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_variables.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_variables.scss similarity index 57% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_variables.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_variables.scss index b60a21368..e8bf3728d 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/_variables.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/_variables.scss @@ -7,3 +7,9 @@ $bd-download: #ffe484 !default; $bd-info: #5bc0de !default; $bd-warning: #f0ad4e !default; $bd-danger: #d9534f !default; + +// Enable responsive font sizes for font sizes defined in the docs +// The weird if test is made as a workaround to prevent a false fusv error. +// +// stylelint-disable-next-line scss/dollar-variable-default +$enable-responsive-font-sizes: if($enable-responsive-font-sizes, true, true); diff --git a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/docs.scss b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/docs.scss similarity index 86% rename from vendor/twbs/bootstrap/site/docs/4.1/assets/scss/docs.scss rename to vendor/twbs/bootstrap/site/docs/4.3/assets/scss/docs.scss index 706bde44e..6b1814dc8 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/assets/scss/docs.scss +++ b/vendor/twbs/bootstrap/site/docs/4.3/assets/scss/docs.scss @@ -1,9 +1,9 @@ /*! * Bootstrap Docs (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under the Creative Commons Attribution 3.0 Unported License. For - * details, see https://creativecommons.org/licenses/by/3.0/. + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the Creative Commons Attribution 3.0 Unported License. + * For details, see https://creativecommons.org/licenses/by/3.0/. */ // Dev notes @@ -34,17 +34,17 @@ @import "masthead"; @import "ads"; @import "content"; -@import "skiplink"; +@import "skippy"; @import "sidebar"; @import "footer"; @import "component-examples"; @import "buttons"; @import "callouts"; -@import "examples"; @import "browser-bugs"; @import "brand"; @import "colors"; @import "clipboard-js"; +@import "placeholder-img"; // Load docs dependencies @import "syntax"; diff --git a/vendor/twbs/bootstrap/site/docs/4.1/browser-bugs.md b/vendor/twbs/bootstrap/site/docs/4.3/browser-bugs.md similarity index 98% rename from vendor/twbs/bootstrap/site/docs/4.1/browser-bugs.md rename to vendor/twbs/bootstrap/site/docs/4.3/browser-bugs.md index 2340f90c2..57818a910 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/browser-bugs.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/browser-bugs.md @@ -2,6 +2,7 @@ layout: docs title: Wall of browser bugs group: browser-bugs +redirect_from: "/browser-bugs/" --- Bootstrap currently works around several outstanding browser bugs in major browsers to deliver the best cross-browser experience possible. Some bugs, like those listed below, cannot be solved by us. diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/alerts.md b/vendor/twbs/bootstrap/site/docs/4.3/components/alerts.md similarity index 96% rename from vendor/twbs/bootstrap/site/docs/4.1/components/alerts.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/alerts.md index 6c6cb9936..2a4bf1026 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/alerts.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/alerts.md @@ -3,6 +3,9 @@ layout: docs title: Alerts description: Provide contextual feedback messages for typical user actions with the handful of available and flexible alert messages. group: components +redirect_from: + - "/components/" + - "/docs/4.3/components/" toc: true --- @@ -97,7 +100,7 @@ Note that closing an alert will remove it from the DOM. | `$().alert('close')` | Closes an alert by removing it from the DOM. If the `.fade` and `.show` classes are present on the element, the alert will fade out before it is removed. | | `$().alert('dispose')` | Destroys an element's alert. | -{% highlight js %}$(".alert").alert('close'){% endhighlight %} +{% highlight js %}$('.alert').alert('close'){% endhighlight %} ### Events @@ -110,6 +113,6 @@ Bootstrap's alert plugin exposes a few events for hooking into alert functionali {% highlight js %} $('#myAlert').on('closed.bs.alert', function () { - // do something… + // do something... }) {% endhighlight %} diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/badge.md b/vendor/twbs/bootstrap/site/docs/4.3/components/badge.md similarity index 83% rename from vendor/twbs/bootstrap/site/docs/4.1/components/badge.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/badge.md index 0e97cbe76..8c1760045 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/badge.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/badge.md @@ -10,23 +10,15 @@ toc: true Badges scale to match the size of the immediate parent element by using relative font sizing and `em` units. -
-
Example heading New
-
Example heading New
-
Example heading New
-
Example heading New
-
Example heading New
-
Example heading New
-
- -{% highlight html %} +{% capture example %}

Example heading New

Example heading New

Example heading New

Example heading New

Example heading New
Example heading New
-{% endhighlight %} +{% endcapture %} +{% include example.html content=example %} Badges can be used as part of links or buttons to provide a counter. diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/breadcrumb.md b/vendor/twbs/bootstrap/site/docs/4.3/components/breadcrumb.md similarity index 97% rename from vendor/twbs/bootstrap/site/docs/4.1/components/breadcrumb.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/breadcrumb.md index 4cc7b3de9..0837e8363 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/breadcrumb.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/breadcrumb.md @@ -33,7 +33,7 @@ group: components ## Changing the separator -Separators are automatically added in CSS through [`::before`](https://developer.mozilla.org/en-US/docs/Web/CSS/::before) and [`content`](https://developer.mozilla.org/en-US/docs/Web/CSS/content). They can be changed by changing `$breadcrumb-divider`. The [quote](https://sass-lang.com/documentation/Sass/Script/Functions.html#quote-instance_method) function is needed to generate the quotes around a string, so if you want `>` as seperator, you can use this: +Separators are automatically added in CSS through [`::before`](https://developer.mozilla.org/en-US/docs/Web/CSS/::before) and [`content`](https://developer.mozilla.org/en-US/docs/Web/CSS/content). They can be changed by changing `$breadcrumb-divider`. The [quote](https://sass-lang.com/documentation/Sass/Script/Functions.html#quote-instance_method) function is needed to generate the quotes around a string, so if you want `>` as separator, you can use this: ```scss $breadcrumb-divider: quote(">"); diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/button-group.md b/vendor/twbs/bootstrap/site/docs/4.3/components/button-group.md similarity index 100% rename from vendor/twbs/bootstrap/site/docs/4.1/components/button-group.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/button-group.md diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/buttons.md b/vendor/twbs/bootstrap/site/docs/4.3/components/buttons.md similarity index 99% rename from vendor/twbs/bootstrap/site/docs/4.1/components/buttons.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/buttons.md index f999fd552..118679752 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/buttons.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/buttons.md @@ -3,7 +3,6 @@ layout: docs title: Buttons description: Use Bootstrap's custom button styles for actions in forms, dialogs, and more with support for multiple sizes, states, and more. group: components -redirect_from: "/docs/4.1/components/" toc: true --- diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/card.md b/vendor/twbs/bootstrap/site/docs/4.3/components/card.md similarity index 87% rename from vendor/twbs/bootstrap/site/docs/4.1/components/card.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/card.md index 25e9ec2d0..fa9c6ffc1 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/card.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/card.md @@ -18,7 +18,7 @@ Below is an example of a basic card with mixed content and a fixed width. Cards {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

Some quick example text to build on the card title and make up the bulk of the card's content.

@@ -70,7 +70,7 @@ Subtitles are used by adding a `.card-subtitle` to a `` tag. If the `.card-t {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}

Some quick example text to build on the card title and make up the bulk of the card's content.

@@ -113,7 +113,7 @@ Mix and match multiple content types to create the card you need, or throw every {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

Some quick example text to build on the card title and make up the bulk of the card's content.

@@ -311,7 +311,7 @@ Add some navigation to a card's header (or block) with Bootstrap's [nav componen Link
@@ -335,7 +335,7 @@ Add some navigation to a card's header (or block) with Bootstrap's [nav componen Link
@@ -358,7 +358,7 @@ Similar to headers and footers, cards can include top and bottom "image caps"— {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -371,7 +371,7 @@ Similar to headers and footers, cards can include top and bottom "image caps"—

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

Last updated 3 mins ago

- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-bottom" text="Image cap" %}
{% endcapture %} {% include example.html content=example %} @@ -382,7 +382,7 @@ Turn an image into a card background and overlay your card's text. Depending on {% capture example %}
- Card image + {% include icons/placeholder.svg width="100%" height="270" class="bd-placeholder-img-lg card-img" text="Card image" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -392,6 +392,33 @@ Turn an image into a card background and overlay your card's text. Depending on {% endcapture %} {% include example.html content=example %} +{% capture callout %} +Note that content should not be larger than the height of the image. If content is larger than the image the content will be displayed outside the image. +{% endcapture %} +{% include callout.html content=callout type="info" %} + +## Horizontal + +Using a combination of grid and utility classes, cards can be made horizontal in a mobile-friendly and responsive way. In the example below, we remove the grid gutters with `.no-gutters` and use `.col-md-*` classes to make the card horizontal at the `md` breakpoint. Further adjustments may be needed depending on your card content. + +{% capture example %} +
+
+
+ {% include icons/placeholder.svg width="100%" height="250" class="" text="Image" %} +
+
+
+
Card title
+

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

+

Last updated 3 mins ago

+
+
+
+
+{% endcapture %} +{% include example.html content=example %} + ## Card styles Cards include various options for customizing their backgrounds, borders, and color. @@ -457,7 +484,7 @@ Use card groups to render cards as a single, attached element with equal width a {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -465,7 +492,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This card has supporting text below as a natural lead-in to additional content.

@@ -473,7 +500,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.

@@ -489,7 +516,7 @@ When using card groups with footers, their content will automatically line up. {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -499,7 +526,7 @@ When using card groups with footers, their content will automatically line up.
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This card has supporting text below as a natural lead-in to additional content.

@@ -509,7 +536,7 @@ When using card groups with footers, their content will automatically line up.
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.

@@ -529,7 +556,7 @@ Need a set of equal width and height cards that aren't attached to one another? {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="200" class="card-img-top" text="Image cap" %}
Card title

This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -537,7 +564,7 @@ Need a set of equal width and height cards that aren't attached to one another?
- Card image cap + {% include icons/placeholder.svg width="100%" height="200" class="card-img-top" text="Image cap" %}
Card title

This card has supporting text below as a natural lead-in to additional content.

@@ -545,7 +572,7 @@ Need a set of equal width and height cards that aren't attached to one another?
- Card image cap + {% include icons/placeholder.svg width="100%" height="200" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.

@@ -561,7 +588,7 @@ Just like with card groups, card footers in decks will automatically line up. {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -571,7 +598,7 @@ Just like with card groups, card footers in decks will automatically line up.
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This card has supporting text below as a natural lead-in to additional content.

@@ -581,7 +608,7 @@ Just like with card groups, card footers in decks will automatically line up.
- Card image cap + {% include icons/placeholder.svg width="100%" height="180" class="card-img-top" text="Image cap" %}
Card title

This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.

@@ -603,7 +630,7 @@ Cards can be organized into [Masonry](https://masonry.desandro.com/)-like column {% capture example %}
- Card image cap + {% include icons/placeholder.svg width="100%" height="160" class="card-img-top" text="Image cap" %}
Card title that wraps to a new line

This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.

@@ -620,7 +647,7 @@ Cards can be organized into [Masonry](https://masonry.desandro.com/)-like column
- Card image cap + {% include icons/placeholder.svg width="100%" height="160" class="card-img-top" text="Image cap" %}
Card title

This card has supporting text below as a natural lead-in to additional content.

@@ -630,7 +657,7 @@ Cards can be organized into [Masonry](https://masonry.desandro.com/)-like column

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.

-
+
Someone famous in Source Title @@ -645,7 +672,7 @@ Cards can be organized into [Masonry](https://masonry.desandro.com/)-like column
- Card image + {% include icons/placeholder.svg width="100%" height="260" class="card-img" text="Card image" %}
diff --git a/vendor/twbs/bootstrap/site/docs/4.1/components/carousel.md b/vendor/twbs/bootstrap/site/docs/4.3/components/carousel.md similarity index 72% rename from vendor/twbs/bootstrap/site/docs/4.1/components/carousel.md rename to vendor/twbs/bootstrap/site/docs/4.3/components/carousel.md index 7c4a0472e..455e2d9e5 100644 --- a/vendor/twbs/bootstrap/site/docs/4.1/components/carousel.md +++ b/vendor/twbs/bootstrap/site/docs/4.3/components/carousel.md @@ -12,6 +12,8 @@ The carousel is a slideshow for cycling through a series of content, built with In browsers where the [Page Visibility API](https://www.w3.org/TR/page-visibility/) is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.). +{% include callout-info-prefersreducedmotion.md %} + Please be aware that nested carousels are not supported, and carousels are generally not compliant with accessibility standards. Lastly, if you're building our JavaScript from source, it [requires `util.js`]({{ site.baseurl }}/docs/{{ site.docs_version }}/getting-started/javascript/#util). @@ -30,13 +32,13 @@ Here's a carousel with slides only. Note the presence of the `.d-block` and `.w- @@ -51,13 +53,13 @@ Adding in the previous and next controls: